July 2011 - Posts
In deze podcast spreekt Maurice de Beijer met Dennis Vroegop over de nieuwe Surface 2. Dennis vertelt ondermeer hoe anders het is een Surface applicatie te maken omdat je rekening moet houden met meerdere gebruikers die aan verschillende kanten van de tafel staan. Ook dat bij veel applicaties mensen zonder enige uitleg toch met de surface moeten kunnen werken maakt dit niet eenvoudiger.
Hier te beluisteren.
Links:
www.TheProblemSolver.nl
www.dotnetevents.nl
When we build services, or write any code for that matter, error can occur and we have to cater for those. With SOAP service we gibe a calling application information about the error by returning a SOAP fault. This SOAP fault is just another piece of XML informing the calling application about whatever was wrong. Now the HTTP protocol also contains a way of sending status information back to the client but when using SOAP that is mostly ignored, all we use is a 200 OK or an 500 Internal Server Error error status. And for one returning a 500 Internal Server Error is really a shame if the error is actually a client problem. But there are far more status codes we can use.
When we are building REST service we embrace HTTP and as a result we also embrace all the HTTP status codes, not just 200 and 500. And that doesn’t just mean with errors but also when everything works as expected as there is a whole range of status codes dealing with success.
In general status code are grouped into a few different categories:
- 1xx is all about information
These are not used a lot. - 2xx is all about success
Whatever the client tried to do was successful up to the point that the response was send. Keep in mind that a status like 202 Accepted doesn’t say anything about the actual result, it only indicates that a request was accepted and is being processed asynchronously. - 3xx is all about redirection
These are all about sending the calling application somewhere else for the actual resource. The best known of these are the 303 See Other and the 301 Moved Permanently which are used a lot on the web to redirect a browser to another URL. - 4xx is all about client errors
With these status codes we indicate that the client has done something invalid and needs to fix the request before resending it. - 5xx is all about service errors
With these status codes we indicate that something went wrong in the service. For example a database connection failed. Typically a client application can retry the request. The server can even specify when the client is allowed to retry the command using a Retry-After HTTP header.
A few success status codes:
- The 200 OK is the generic success status when there is nothing special to report.
- The 201 Created status is used to indicate that a new resource has been created. This response usually also contains a Location header to indicate the URL of the newly created resource.
- The 204 No Content is used when we conditionally retrieve some data. For example when using an ETag and asking for the data only if it has been modified using the If-None-Match HTTP header.
A few client failure status codes:
-
A very common client failure status code happens when the client fails provide it’s credentials for a secured service. In that case the service would return a
401 Unauthorized status. The service response will also contain a
WWW-Authenticate header informing the client of the way it wants it to authenticate.
- Another common failure is when the client application asks for some non existent resource. In that case a 404 Not Found status is returned to the client.
A few service failure status codes:
- The generic service side error status is the 500 Internal Server Error which doesn’t give the client a lot of information
- Another useful status code is the 503 Service Unavailable informing the client application that the service can’t be used at the moment. This could be for any number of reasons but for example because the database used is in a backup procedure. Typically the service also adds a Retry-After HTTP header if it can to indicate to the client that it can retry after a specific period.
Check here for a complete list of all HTTP status codes.
Using HTTP status codes with the WCF Web API
returning custom HTTP status codes with the WCF Web API is quite easy. Lets start with the following very simple example function:
[WebGet(UriTemplate = "/{id}")]
Book GetBook(int id)
{
var result = _repo.GetBook(id);
return result;
}
If I request the books resource using the URL http://localhost:28330/books/1 I get the following.

That’s just fine and exactly what I would expect. However if I use the URL http://localhost:28330/books/999 to get a book with id 999 which doesn’t exist I see the following:

Not exactly what I want, there is no book found and yet it returns a null book resource.
The fix is quite simple. If we want more control over the response we don’t just return the resource but we return a HttpResponseMessage<T>. Using the HttpResponseMessage<T> we can set all sorts of headers but in this case we are only interested in setting the HttpStatusCode to NotFound if the requested book doesn’t exist.
[WebGet(UriTemplate = "/{id}")]
HttpResponseMessage<Book> GetBook(int id)
{
HttpResponseMessage<Book> result;
var book = _repo.GetBook(id);
if (book != null)
{
result = new HttpResponseMessage<Book>(book);
}
else
{
result = new HttpResponseMessage<Book>(HttpStatusCode.NotFound);
}
return result;
}
When we try the same URL again with the new function we get the following result:

Note that Internet Explorer is focused on web pages not books so it tells us that the webpage is not found and the page header contains the actual HttpStatusCode returned, 404 Not Found in this case.
Besides setting the HttpStatusCode instead of a resource in the constructor we can also set it as a property like this:
result.StatusCode = HttpStatusCode.Created;
Just remember that setting a resource, even a null one, will return that to the calling application so in this case where we want to make sure there is no body we have to be very explicit about it.
Enjoy!
www.TheProblemSolver.nl
www.dotnetevents.nl
Sorry Dutch language only.
Mijn artikel over het ontwikkelen van REST services met de WCF Web API is nu online. Het is hier te vinden.
Enjoy!
www.TheProblemSolver.nl
www.dotnetevents.nl
A reader posted a question in my blog post about REST services and URL’s about modeling search and login as a resource. As this is an important concept I decided not to add a comment but write another blog post about this.
About using http://localhost/login as a URL in a REST service
The URL http://localhost/login suggest that there is a resource login while login clearly is an action, not a resource. You don’t create or delete logins. Now you might create user sessions and in that case you might have a URL like http://localhost/UserSession where you can create and delete a users session.
Another, unrelated to the URL, thing here is that REST services should be stateless in order to promote scalability. Therefor it is better not to start a session, do a number of requests and log out. No you should consider each request completely unrelated to the others and if you need to authorize users then each request should contain the required user information.
About using http://localhost/books/search/robot to search for books with robots
This one is a little harder and depends on you point of view. I would argue that search is another action and not a resource so it should not be part of the URL. Maybe we use the http://localhost/books URL with a search method header, more about HTTP methods in another blog post. or a query string like http://localhost/books?$search=robot to indicate we want to search for books about robots.
Now someone could argue that the fact the books are resources and searching would return a collection of books and I would completely agree. So as it returns a collection of resources you might think this is an appropriate URL scheme to use and I would disagree. But I am also pragmatic in these cases and it is about the end result, not about being right or wrong. So of you want to use this URL to search go with it. Just remember I am not that pragmatic that I am also going to agree about the login 
How the URL is actually constructed using the WCF Web API
When we start constructing our URL there are three different parts that combine the complete URL. Given the URL http://localhost:28330/books/12345 the first part if the base address. This is the http://localhost:28330/ part and is determined by IIS in the case of managed hosting or the base address specified in the case of self hosting. The next part of books/ and that is determined by the path specified when we do the routes.MapServiceRoute<T>(path) like in this example:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
var builder = HttpHostConfiguration.Create();
routes.MapServiceRoute<BooksService>("books", builder);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
The last part, the 12345 in the example URL, is determined by the UriTemplate property of the WebGetAttribute used in our service contract. This can be an empty string, as in the GetBooks() example, to use the service route of http://localhost:28330/books which is typically reserved for the collection. It can also be templated, like in the GetBook() example, to specify variable parts that match input parameters. In this case {id} matched the id parameter. This can be further enhanced with fixed and variable strings like http://localhost:28330/books/12345/orders/6789 and a template of /{id}/orders/{orderId} to return a specific order from the collection of orders containing book 12345.
[WebGet(UriTemplate = "")]
List<Book> GetBooks()
{
var result = _repo.GetBooks();
return result;
}
[WebGet(UriTemplate = "/{id}")]
Book GetBook(int id)
{
var result = _repo.GetBook(id);
return result;
}
Enjoy!
www.TheProblemSolver.nl
www.dotnetevents.nl
When designing and building REST services the URL’s used take on a rather important part. So it pays to think a lot about the URL structure up front.
Basically a URL is used to identity a recourse. So it kind of behaved like a primary key in a database. There are a few big differences to keep in mind. Unlike a primary key a resource can have multiple URL’s pointing to the same resource. Another difference is that we often have a URL for a collection of the same items. So for example:
Some things are not resources. An often made mistake is to model operations using the same URL scheme. For example:
- http://localhost/books/search/robot
This would search the book collection for books about robots. But searching is an operation so I believe that this should be modeled using the http://localhost/books URL and either add a filter using either query parameter or an HTTP header. - http://localhost/login
Login in is definitely an action and not a resource we can retrieve. And secondly it suggest some shared state between the client and the service, another thing that is better to avoid.
This might seem simple enough, and it really isn’t rocket science, but it can still be harder that it seems. And remember that the URL is just there to identity a resource, it doesn’t really tell us what we can do with it yet. In some cases all we can do is GET the resource but in other cases we can add new ones using the URL or we can update or delete existing resources.
Enjoy!
www.TheProblemSolver.nl
www.dotnetevents.nl
In this podcast Maurice de Beijer speaks with Scott Hanselman about web development. They discuss the move of Scott Guthrie to the Azure team and what this will mean for the average web developer. They also talk about WebMatrix, iCloud and scalability amongst other things.
The first English language podcast for the DotNed community 
http://dotned.nl/PodCasts.aspx?id=11
Enjoy!
www.TheProblemSolver.nl
www.dotnetevents.nl