I have moved my active blog over to tumblr. I've maintained this blog for reference but will be posting to http://www.robustsoftware.co.uk instead. I've pointed my Feedburner feed to tumblr so if you're subscribed already you should already have switched with me.

POST overload – implementation considerations

As I have been blogging about, I’ve been fighting with myself over the best way to implement POST overloading in RESTful ASP.NET MVC. I’m still not happy that I have chosen the best implementation in using the URL to indicate the overload but I’m done with thinking about it for now. I’m going to record my and others thoughts about the pros and cons of each approach and move on to other functionality.

The two main points around which the discussion revolves are transparency and adherence to the spirit of HTTP. A compromise has to be made on one of them, which you choose to compromise, I feel, is a personal decision.

Using a hidden form value for overloading is transparent to the user, the URL the POST is made to does not change. My previous argument for needing to implement overloading for different content types is nonsense as you would never need to use POST overloading apart from when POSTing a form from a browser. All other calls will be able to use the correct HTTP verb directly.

The URL overloading method, for me, remains closer to the spirit of HTTP. If the URL contains the overload you know how to handle the request purely from the head of the HTTP request. Using the form value method you need to check the body of the HTTP request to know what to do.

Neither method is ideal, they both have their compromises and I can’t honestly say whether one is better than the other at the moment. Perhaps I’ll obtain some insight later that makes one clearly better than the other. However, I do know that at the moment I’m risking the wrath of Scott Bellware:

@gshutler ultimately, i'm gonna come gunning for you if this hack-in-the-uri becomes convention in the late-to-the-game .net rest users :) Sat 25 Jul 01:20

If you find me in a ditch because everyone starts using the URL overload method, you have a prime suspect.

I’d like to thank Scott Bellware and Sebastien Lambla for taking the time to talk to me about this subject over the past couple of weeks on twitter, it’s greatly appreciated.

Overloading POST – a change of mind

Today I made a fairly fundamental change in design of RESTful ASP.NET MVC revolving around how I will be overloading post for HTML forms.

Previously I was adding a hidden field to the form, which is how it is done by Rails:

<form method="POST" action="/Users/2">
<input value="DELETE" type="hidden" name="_method" />
<input value="Delete" type="submit" />
</form>

I was aware of OpenRasta's method of overloading post which is to append the overload to the URI:

<form method="POST" action="/Users/2!DELETE">
<input value="Delete" type="submit" />
</form>

However, I didn’t like the way the overload was opaque to the user and thinking that the Rails guys must have thought about it a fair bit I initially went with the former method.

I ended up having a discussion with Sebastien Lambla, the developer of OpenRasta, about the two options and why he had chosen the second method over the first (I love twitter for this). To be honest, I came away from the discussion thinking there wasn’t much to chose between the two, it just being down to a matter of preference. However, I kept thinking about it, questioning my decision and whether it my choice really was better than the other option.

I had a moment of clarity whilst playing golf. I realised that, potentially, I might have to write post overload mechanisms for multiple formats as clients could submit requests in a variety of formats (XML, JSON, form, etc). If the overload is contained within the URL then the overload is independent of the body’s content type, simplifying things considerably.

Now I had a reason to change, I did so, changing RESTful ASP.NET MVC’s method of overloading post to the URI mechanism. As it happens this tidied up the code a little as I no longer had to pass around the form collection, I could work purely off the routing values.

Related posts:

You should subscribe to my feed to keep up with development of RESTful ASP.NET MVC.

UPDATE

I have written a follow-up post about the implementation considerations for POST overload that I recommend reading as well.

ASP.NET MVC Route Testing with HTTP Verbs

I’ve started RESTful ASP.NET MVC from scratch and I am test-driving it. Writing code without tests is ok for proofs of concept but as I was planning on continually adding to the project I felt I had to start again and make sure everything was tested. As part of the process I was looking to test my routing rules. I used Phil Haack’s route testing helper as a starting point but I think I’ve customised it enough to warrant a post.

The first thing I did was change his static method into an extension method. However, my routes were also dependant upon the HTTP verb used so I had to add that in on top. I also needed to check that a route wouldn’t be matched for the same reason as a URI which is valid for a GET may not be valid for a POST.

My route test helper and an example of it in action from the test-driven branch of restful-aspmvc.

Related posts

RESTful ASP.NET MVC

This is the first in what could be a series of posts on how to modify the internals of ASP.NET MVC in order to make it work in a more RESTful manner. If you want to work with a RESTful web framework built on .NET today then I recommend using OpenRasta.

The reason I’m doing this is two-fold:

  1. I want to learn more about REST beyond the theory and I learn more by doing.
  2. Sometimes it’s impossible to convince people to use an open source framework like OpenRasta, but customising stuff produced by Microsoft is much better received. I hope this will help other people write more RESTful sites whilst using Microsoft-based frameworks.

All the code I will be referring to is available on the restful-aspmvc project page. At the time of writing this the code was on revision 3, so if you are reading this later on there my be some inconsistencies.

The inspiration

I wanted to be able to use RESTful URLs like those available in Ruby on Rails. These work by selecting the controller action through the use of the URL and the HTTP verb.

GET /users/               UsersController.Index()
POST /users/              UsersController.Create()
GET /users/{id}           UsersController.Show(id)
PUT /users/{id}           UsersController.Update(id)
DELETE /users/{id}        UsersController.Destroy(id)

I then wanted to allow you to create different views of the resources by specifying other actions that can only use the GET verb like so:

GET /users/{action}       UsersController.{Action}()
GET /users/{id}/{action}  UsersController.{Action}(id)

The implementation

The above routes are achieved through these route mappings: listing on Google code

The next problem was to map to the different actions according to the URL and the HTTP verb. As web browsers only support GET and POST this requires a technique known as overloading POST. I tried doing this in a couple of ways, firstly by including the required HTTP verb in the URL:

/users/{id}?verb=DELETE

However, I found this quite ugly. As we are overloading POST, there will always be a form involved, therefore I’ve specified the required verb (where necessary) with a hidden form field:

<form method="post" action="/Users/2">
<input value="DELETE" type="hidden" name="_verb" />
<p>
<input value="Delete" type="submit" />
</p>
</form>

Now the verb is specified in the form, we have our URLs working we now need to act on this information. For that I have used a customer controller factory (Google code listing).

There’s a fair bit of code to include directly into a blog post so I’ll explain the general flow to you and if you’re interested in the implementation you can have a look at the listing.

  1. When the controller is created we use the default implementation to retrieve the controller and give it a custom action invoker to use.
  2. When the action is invoked we first check if the verb being used is a POST, if it is we check the form for an override. If one exists we change what we think the HTTP verb is to the one passed.
  3. If no specific action has been used (the default action is Index because of the routes we specified) then we use the HTTP verb and whether an id was specified to determine the actual action required.
  4. We use the default implementation to invoke the action required.

The full code listing includes a basic site which shows all the overrides being used along with a couple of common custom views (new and edit are commonly used to display forms to create and update resources).

This is the first step towards making ASP.NET MVC more RESTful. I welcome your comments and feedback, especially if there is something in particular you’d like me to implement in the future.

REST – a quick summary

I’d read a lot of blogs talking about REST and it’s benefits but I hadn’t fully got it. Whilst on holiday I read RESTful Web Services, which I had seen recommended, in an effort to try and finally grok REST.

I thoroughly recommend this book, it helped me connect a lot of previously separate ideas into a coherent whole. What I hope to do here is give an overview of what I’ve learnt from the book to act as a reference to myself and maybe help other people in the process.

Definition

REST is short for Representational State Transfer. Distilled down, it’s basically about using the HTTP verbs, GET, POST, PUT, DELETE and HEAD, in order to act on resources, represented by individual URIs.

Resources are similar to what most of you will think of as domain entities. However, a relationship between two entities can be represented by a resource.

Underlying principle

The main idea behind REST is that you are working with the HTTP protocol. Other web service ideas like SOAP, referred to in the book as Big Web Services, mostly ignore the expressiveness of the HTTP protocol and use only GET and/or POST requests. This often works against the HTTP protocol, at best it ignores .

The requests and responses of the HTTP protocol consist of a head and a body. The analogy used in the book is one of an envelope, the head being the envelope and the body being the contents of the envelope. REST uses the URI, HTTP verbs, HTTP headers and HTTP response codes in order to communicate to the server what is wanted and to the client what happened.

This is in contrast to SOAP which generally uses the URI from the head and then sends another envelope in the body to communicate more information about the request to the server and the response to the client. This is effectively putting an envelope inside another envelope.

HTTP verbs and their meanings

The beauty of the verbs are that they are mostly self-explanatory, but I’ll explain all of them for completeness.

GET

This verb means give me the current representation for the given URI. You can use headers to modify the behaviour slightly. For example, the If-Modified-Since header can be used to say “only send me the representation for the URI if it has changed since the given date”. This can be used to minimize needless traffic and processing.

DELETE

This verb means delete the representation at the given URI. There’s not really anything complicated about it.

HEAD

This is equivalent to a GET request but only returns the HEAD of the response, omitting the BODY. This is used for getting the meta data about a resource, for example checking whether a resource exists at a given URI without retrieving the BODY as well.

POST and PUT

I’ve put these two together as they are the ones I previously had most difficulty differentiating between. Needless to say the book explained the difference perfectly.

PUT is used to place a resource to a specific URI (eg. /Product/1), this can be a resource that didn’t exist before (an insert) or replace the existing representation at that URI (an update). In contrast, POST is used to add a resource to the end of a list of resources (eg. /Product) when you don’t know the URI in advance (an insert). Once you know the URI of your new resource, you will use a PUT to update it.

REST and HTML forms

A problem I had was reuse of web service code with web sites, HTML only supports the verbs GET and POST. I was concerned about having to maintain two sets of code for acting on the same resources. This can be overcome by using a concept called overloaded post.

The idea behind it is really simple, you include the verb you want to use as a query string parameter and POST to that URI (eg. /Product/1?method=DELETE). Then using some simple server-side code you handle the request as the verb passed instead of as a POST.

Conclusion

I’ve covered the main concepts that helped me understand the big picture of REST. I really think it is the best way to write web services so that they can be easily consumed by other people. The emphasis of REST is on simplicity, utilising the power of the HTTP protocol rather than building a new protocol on top of it. This goes against the common practice up until this point, which to me is a breath of fresh air.

Finally, I strongly recommend you buy the book if you are interested in learning more about REST.

Nott Tuesday and the altnetbeers format

As I said previously I’ve volunteered to lead this month’s Nott Tuesday event, taking place this coming Tuesday, 14th July.

So, as promised, I’m going to give the outline of how the whole evening will work. Hopefully it will encourage more participation from the whole group in the discussion, improving the night for everyone.

Topic selection

So a little while after 18:30, once everyone has had the chance to say hellos and so forth, I’ll ask everyone to volunteer topics for discussion. I’ll provide a stack of index cards and pens and anyone who has something they’d like to talk about can write a question on a card and put it onto a table for others to see. Something as vague as “why agile?” or specific as “how do I leverage e-marketing to obtain new business?” is fine. Framing it as a question will probably work better, but if you can’t do that then a simple sentence will do. The idea is to give the group a starting point for a discussion.

Once we’ve had 5-10 minutes to write down our ideas we will whittle them down to the few most popular topics by voting on the ideas as a group. We’ll start off with the most popular topic and if the discussion is lively enough for long enough that might be all we discuss all night but if things start tailing off we’ll move on to the next most popular topic.

How does the discussion work?

There will be a “bench” where 3 people sit, they are the panel of which the group can ask questions. To begin with I’ll ask whichever person raised the topic to speak for 30 seconds or so just to explain a bit further what they want to get from the discussion. This person will also start off on the bench along with 2 volunteers. It is then thrown to the floor to ask questions of the bench. If you have a question, raise your hand and I’ll pick a person at a time to ask their question to stop it being a free-for-all. If you are part of the audience, you can only ask questions or come back on the answers given by the panel when applicable.

If it is a topic you are interested in and have something to say about it, you can go and sit in the “hot seat”, this signifies you want to be on the bench and answer questions. When someone is in the hot seat, someone from the bench is obliged to return to the audience, allowing the person in the hot seat to move onto the bench. This can manage itself by people not having more to say or wanting a break, but if not we’ll do it on a first-in-first-out basis.

A personal plea

Please be gentle with me, it’s the first time I’ve run something like this so bear with me a bit. I might need to cut you off if you’re in the middle of a heated discussion but the majority of the room looks bored, please bear in mind I’m trying to keep it interesting for the whole group. There’s nothing to stop your carrying on the discussion afterwards of course!

That’s all there is to it really. Hopefully, it will result in an enjoyable evening for everyone, having lively discussions about topics we’re all interested in.

See you at Bluu on Tuesday 14th July at 18:30!