views:

355

answers:

2

I'm trying to develop a simple REST API. I'm still trying to understand the basic architectural paradigms for it. I need some help with the following:

  1. "Resources" should be nouns, right? So, I should have "user", not "getUser", right?

  2. I've seen this approach in some APIs: www.domain.com/users/ (returns list), www.domain.com/users/user (do something specific to a user). Is this approach good?

  3. In most examples I've seen, the input and output values are usually just name/value pairs (e.g. color='red'). What if I wanted to send or return something more complex than that? Am I forced to deal with XML only?

  4. Assume a PUT to /user/ method to add a new user to the system. What would be a good format for input parameter (assume the only fields needed are 'username' and 'password')? What would be a good response if the user is successful? What if the user has failed (and I want to return a descriptive error message)?

  5. What is a good & simple approach to authentication & authorization? I'd like to restrict most of the methods to users who have "logged in" successfully. Is passing username/password at each call OK? Is passing a token considered more secured (if so, how should this be implemented in terms of expiration, etc.)?

+6  A: 

For point 1, yes. Nouns are expected.

For point 2, I'd expect /users to give me a list of users. I'd expect /users/123 to give me a particular user.

For point 3, you can return anything. Your client can specify what it wants. e.g. text/xml, application/json etc. by using an HTTP request header, and you should comply as much as you can with that request (although you may only handle, say, text/xml - that would be reasonable in a lot of situations).

For point 4, I'd expect POST to create a new user. PUT would update an existing object. For reporting success or errors, you should be using the existing HTTP success/error codes. e.g. 200 OK. See this SO answer for more info.

Brian Agnew
+3  A: 

Hi StackOverflowNewbie,

the most important constraint of REST is the hypermedia constraint ("hypertext as the engine of application state"). Think of your Web application as a state machine where each state can be requested by the client (e.g. GET /user/1).Once the client has one such state (think: a user looking at a Web page) it sees a bunch of links that it can follow to go to a next state in the application. For example, there might be a link from the 'user state' that the client can follow to go to the details state.

This way, the server presents the client the application's state machine one state at a time at runtime. The clever thing: since the state machine is discovered at runtime on state at a time, the server can dynamically change the state machine at runtime.

Having said that...

on 1. the resources essentially represent the application states you want to present to the client. The will often closely match domain objects (e.g. user) but make sure you understand that the representations you provide for them are not simply serialized domain objects but states of your Web application.

Thinking in terms of GET /users/123 is fine. Do NOT place any action inside a URI. Although not harmful (it is just an opaque string) it is confusing to say the least.

on 2. As Brian said. You might want to take a look at the Atom Publishing Protocol RFC (5023) because it explains create/read/update cycles pretty well.

on 3. Focus on document oriented messages. Media types are an essential part of REST because they provide the application semantics (completely). Do not use generic types such as application/xml or application/json as you'll couple your clients and servers around the often implicit schema. If nothing fits your needs, just make up your own type.

Maybe you are interested in an example I am hacking together using UBL: http://www.nordsc.com/blog/?cat=13

on 4. Normally, use POST /users/ for creation. Have a look at RFC 5023 - this will clarify that. It is an easy to understand spec.

on 5. Since you cannot use sessions (stateful server) and be RESTful you have to send credentials in every request. Various HTTP auth schemes handle that already. It is also important with regard to caching because the HTTP Authorization header has special specified semantics to caches (no public caching). If you stuff your credentials into a cookie, you loose that important piece.

All HTTP status codes have a certain application semantic. Use them, do not tunnel your own error semantics through HTTP.

You can come visit #rest IRC or join rest-discuss on Yahoo for detailed discussions.

Jan

Jan Algermissen
Can you expand on the generic types ? text/xml doesn't by itself specify a schema, so I'm a little confused by your comments re. point 3. An example may work well here.
Brian Agnew
Media types tell the recipient of an HTTP message what the semantics of the message are. Generic types do not have any kind of useful semantic for the application. If you receive an application/xml message, all you basically know is that you can stuff it into an XML parser, that's all. If the intention is to send an order, the recipient must be able to understand that from the media type.If you send generic types and client and server rely on e.g. the XML to have a certain form client and server are coupled by that out-of-band semantic.In addition, the message is not self-desribing.Better?
Jan Algermissen
Yes. I see where you're coming from. So in an application with a large domain model would you recommend multiple types e.g. application/user, application/trade etc.?
Brian Agnew
That depends on what existing media types you can reuse and the domain as such (IMHO, media type design is still a to-be researched area and Roy Fielding did not manage to put that chapter in his dissertation because, as he said, he ran out of time).You might want to look at an example project of mine regarding procurement and the Universal Business Language: http://www.nordsc.com/blog/?cat=13 Maybe there are some ideas in there that can help you.As a rule of thumb I'd try to use a 'bigger' media type with several XML root elements (if you go XML).
Jan Algermissen