Introduction
After making the example to fit a restful design in struts 1.x, I began investigating which rules exist to create a URI. A URI should be a simple representation but as I we all know, making things simple is the hardest thing to do.I found some blogposts talking about this topic:
- It started with Dave Thomas,
- then Robert Hahn responded to it and
- Pat Maddox didn't fully agree.
I also think there are more cases that need to be handled, for example
- doing a search for a resource,
- performing a calculation,
- showing partial information of a resource,
- showing an aggregated view of multiple resources,
- ...
In this blog post I won't take in account that a normal browser request can't change the Accept header and can't send any thing else than GET and POST. These shortcomings will need to be emulated in some way.
Identified resources
GET /resource/1 : Showing a single resource with identifier 1. We could also do GET /resources/1 which would be more of a search but since it only returns one item I agree with Robert Hahn that the first representation is the best.Using the different http methods we get:- POST /resource/1 : Add a resource and use identifier 1 (in a lot of cases, this will make no sense since the identifier will be created by the server or database)
- PUT /resource/1 : Update the resource with identifier 1
- DELETE /resource/1 : Delete the resource with identifier 1
A newly created resource
- GET /resource : Get the input form to create a new resource
- POST /resource : Create a new resource. The result should be a redirect to GET /resource/new_id
Searching a resource
GET /resource?field=searchvalue&field2=searchvalue2 : Searching is why request parameters exist so use them for this. A very complex search could be handled in the same way as a calculation.Multiple representations of the same resource
Multiple representations should be retrieved using a different Accept header. Problem is that in the browser, the request header can only be set when doing an AJAX request. For links, you are stuck with what the browser provides.Aggregated view of multiple resources
I think this is just a different view (=Accept Header) for a resource. Thus information of a person with his address would be GET /person/1/address with an Accept header text/vnd.app.person+address.What if you want to see or edit a person with his address and orders on one screen? I assume something of the following: GET /person/1/address+orders would do. The address and the orders are related to the person and not to each other thus GET /person/1/address/orders would be wrong.
Calculation
Calculations are a two step process. This first is creation of the calculation, the second retrieval of the result. Thus a POST /calculation would be redirected to return a GET /calculation/123 . If this calculation is long running, the GET could be polled to check if the result is already available. The nice thing of this is that you could bookmark the result or send it to someone else without redoing the calculation.This solution also has its impact on the server side. The result of the calculation will need to be stored somewhere or a 410 Gone should be returned (this could also be a 404 if there was no result with the given id but how are you going to know this?)
Other REST issues to think about
- Governance of URI's: As for SOAP web services, REST web services should be reusable. A certain amount of governance is needed to achieve this across projects. I found the following nice article on infoq. It doesn't give any satisfying solution but still a nice read.
- How to get links in your response in an easy manner?
- Maybe I should see REST less as "returning a presentation" and more as "providing a service". It needs a smart client to talk to services, a dumb client (=browser) can only show a representation. In this, I follow the article of Dave Thomas.
- Circumvent the problem that in a browser could can't set the Accept header (or any other header) in the request. Same for PUT and DELETE, this is supported by google with a hidden field in a POST request that is on the serverside translated.
- Add your own ...

0 reacties:
Post a Comment