It's pretty straight forward, just do the following:
- Use HTTP verbs: GET to retrieve one or more objects, POST to create a new object, PUT to update an existing object, DELETE to remove an object.
- Address objects by collection and by individual object: /users/#{user_id} is a specific user you can PUT, GET or DELETE. /users is where you POST to in order to create a new user.
- Use HTTP codes to return the result back to the client (ie HTTP 200 when you get an object, 201 when you successfully POST an object, 404 when you try to GET/UPDATE/DELETE an object that doesn't exist).
- I find it good form to return objects in JSON with the type of object at the top of the data structure, ie {:users => [ #array of users here ]} or {:user => { #single user }}
- Use OAuth or some sort of token system for authenticating the calls, don't use HTTP Auth.
You can get pretty anal about things but if you follow the above you'll have a cleaner API than 90% of the API's out there.
> Use HTTP verbs: GET to retrieve one or more objects, POST to create a new object, PUT to update an existing object, DELETE to remove an object.
You forgot PUT to create a new object and POST to update an existing object.
> Address objects by collection and by individual object: /users/#{user_id} is a specific user
As far as REST is concerned, that doesn't really matter. The important thing is that the client doesn't generate the "/users/#{user_id}" URLs itself, but rather selects a URL from those it has been told about.
> I find it good form to return objects in JSON with the type of object at the top of the data structure, ie {:users => [ #array of users here ]} or {:user => { #single user }}
A big dumb mistake this api makes is sending commands and object ids via query parameters, instead of making them part of the url. The url should look like a file path that addresses an object -- the path of the objects shouldn't be in a query parameter. Especially when the object you're addressing is a file that has a logical location specified by a path.
- Use HTTP verbs: GET to retrieve one or more objects, POST to create a new object, PUT to update an existing object, DELETE to remove an object.
- Address objects by collection and by individual object: /users/#{user_id} is a specific user you can PUT, GET or DELETE. /users is where you POST to in order to create a new user.
- Use HTTP codes to return the result back to the client (ie HTTP 200 when you get an object, 201 when you successfully POST an object, 404 when you try to GET/UPDATE/DELETE an object that doesn't exist).
- I find it good form to return objects in JSON with the type of object at the top of the data structure, ie {:users => [ #array of users here ]} or {:user => { #single user }}
- Use OAuth or some sort of token system for authenticating the calls, don't use HTTP Auth.
You can get pretty anal about things but if you follow the above you'll have a cleaner API than 90% of the API's out there.