Author
Gian ZasGian Zas leads Moove It’s Software Engineering Studio. As a technical architect he has worked with several of our clients on their key technical challenges and has specific expertise in finance. He studied programming at Uruguay’s ORT University.
– Every resource is identified by an URI
The URI <base_uri>/car/<car_id> identifies the car whose ID is <car_id>. If you are designing an API to interact with a software system, the ID probably will be the primary key of the car in the database
– Use the HTTP Verbs.
GET <base_uri>/car/<car_id> -> This operation retrieves information about the car whose id is car_id. No side effects here, please!
GET <base_uri>/cars -> Retrieves the set of cars, parameters containing the page_size and page_number are highly recommended. No side effects.
POST <base_uri>/car -> Create a new car, the car attributes are passed as HTTP parameters. This operation must retrieve the ID of the new object created.
PUT <base_uri>/car/<car_id> -> Modify the data associated with the car, the attributes are passed as HTTP parameters
DELETE <base_uri>/car/<car_id> -> You want to delete an object? Just it!
Don’t use action names, like get_car, or browse_for_id in the URI, the verbs indicate the desired action
A principle-design discussion… singular or plural nouns at the URI? Personally I prefer nouns in singular for operations involving ONE resource, and plural for MORE than one resource.
– Use of HTTP Status codes
Use it to indicate the result of the operation.
I recommend that the API return appropriate HTTP status codes for each request.
200 OK: The request has been successfully completed.
304 Not Modified: Operation ok. There was no new data to return
400 Bad Request: The request is invalid. Error messages are returned for explanation purposes.
401 Not Authorized: The credentials provided are invalid or are needed for the operation.
403 Forbidden: The request is refused by the API implementation. Error messages are returned.
404 Not Found: The resource requested doesn’t exist. Ex: The provided car_id in the url doesn’t exist.
500 Internal Server Error: An unrecoverable error has occurred at server side.
502 Bad Gateway: The API service is down or being upgraded
503 Service Unavailable: The service is overloaded with a lot requests and can’t manage the incoming request.
– Error Messages
When the API returns error messages it must comply with a structure. Here I present a simple structure in JSON format:
{ error_messages: [ "error_message_1", "error_message_2", ..., "error_message_n" ] }
– Data Format
The operations return information about the resource requested or information about error messages. The format of that information could be preferably at the moment JSON or XML.
If you will be supporting more than one format, or think that in future you’ll be, a possible manner is to include the format at the URI, for example:
PUT <base_uri>/car.json/<car_id>
PUT <base_uri>/car.xml/<car_id>
Conclusion: The key base-aspects of designing a RESTful API are
– Identify every resource (or object in OOP idiom) with an URI
– Use HTTP verbs
– Use HTTP status code
– Don’t use action names in the URI
An important implementation detail: Use UTF-8, unless your data is only on languages with high code points (digging more in the cloud about this topic is recommended)
Another important aspect is about security access to the operation, but is an subject for a future post, stay tuned!