I am building a website and also want to build a REST web service for accessing a lot of the same functionality (using google app engine and spring mvc3), and I’m not sure of the best practices for how integrated/separate the 2 parts should be.
For example if I want view a resource I can provide a url in the form:
{resourcetype}\{resourceid}
A GET request to this url can be redirected at a view which generates a webpage when the client is HTML/browser based. Spring has (from what I read – not tried it yet) the ability to use this same resource URL to serve up a view which returns HTML/Xml/JSON depending on the content type. This all seems great.
POST requests to a URL to create new resources in REST should return 201 CREATED (or so I read) along with the URL of the created resource, which seems fine for the Api but seems a little different from what would be expected from the norm in a web page (where you would likely be redirected to a page showing the resource you created or to a page saying it was created successfully or similar). Should I handle this by serving up a page at a different URL which contains the form for creating the resource, then submits to the Api URL via ajax and gets the response and redirects to the resource URL included in the response.
This pattern seems like it would work (and should work for DELETE too) but is this a good approach or am I better keeping the REST Api URLs and the web site URLs separate? this seems like it could introduce a fair bit of duplication and extra work. But having a single URL could mean that you are dependent on javascript being available on the client of a HTML 5 supporting browser.
I disagree with Michael’s answer and use it as a basis for my own:
To “decouple your web urls from you API urls so they can each change indepentently.” is to spit in the face of REST. Cool URIs don’t change. Don’t concern yourself with changing your URLs. Don’t version your API using URIs. REST uses links to espouse the OCP – a client operating on the previous version of your API should happily follow the links that existed when it went live, unknowing of new links that you’ve added to enhance your API.
If you insist on versioning your API, I’d ask that you do so using the media type, not the URI.
Next, ” you simplify your implementation. Now every method doesn’t have to determine if it’s fronting JSON/XML or HTML.”
If you’re doing it this way, you’re doing it wrong. Coming from Jersey, I return the same damn object from every method whether or not I produce HTML, XML or JSON. That’s a completely cross-cutting concern that a marshaller takes care of. I use a VelocityMessageBodyWriter to emit HTML templates surrounding my REST representations.
Every resource in my system follows the same basic behavior:
The GET method may need to build Links to other resources. These are used by consumers of a REST API as well as the HTML template. A form may have to POST and I use some particular Link (defined by the Relation) for the “action” attribute).
The path through the system may be different between a user-browser and a user-machine but this is not a separation of implementation – it is REST! The state transfer happens how it needs to, how you define it. How users (in a browser) proceed.
“Finally, by separating the site from the API, you allow for different scaling needs. If your API is getting hit hard but not the website, you can throw more hardware at the API while keeping the minimal needed for the website.” – your scaling should not depend on who uses what here. Odds are you’re doing some work behind the scenes that is more intense than just serving up HTML. By using the same implementation, scaling is even easier. The API itself (the marshaling between XML and domain objects and back) is not going to exceed the business logic and processing, database, etc.
Lastly, by keeping them the same, it is much easier to think about your system as a whole. In fact, start with the HTML. Define the relationships. If you’re having a hard time expressing a particular action or user story in HTML anchors and forms, you’re probably straying from REST.
Remember, you’re expressing things as links (of a particular relation) to other things. Those URIs can even be different depending on whether you’re producing XML or HTML – the HTML page might POST to URI some/uri/a and the API might POST to some/uri/b – that’s irrelevant and being concerned with what the actual URI contents are is the dark path to POX and RPC
Another nifty feature is that if you do it this way, you’re not dependent on JavaScript. You’ve defined your system to work with basic HTML and you can ‘flip on’ JavaScript when it is available. Then you’re really working with your “API” anyway (I cringe at referring to them as different things, but I’m also trying to bridge my response in to your wording)
** I will add one final comment, when producing HTML, I use 303 instead of 201 in order to facilitate POST-then-GET. If JS is enabled, you’re actually talking XML (or JSON) and you’re back to 201.