Representational State Transfer (REST) is an architectural style that defines a set of constraints to be used for creating web services. A client requests some data from the server and the server returns the data(resource). There are 6 Constraints –
- Uniform Interface – It is a key constraint that differentiate between a REST API and Non-REST API. It suggests that there should be an uniform way of interacting with a given server irrespective of device or type of application (website, mobile app).
- Stateless – The server will not store anything about the latest HTTP request the client made. It will treat every request as new.
- Cacheable – Every response should include whether the response is cacheable or not and for how much duration responses can be cached at the client side.
- Caching – Caching is the ability to store copies of frequently accessed data in several places along the request-response path. When a consumer requests a resource representation, the request goes through a cache or a series of caches (local cache, proxy cache, or reverse proxy) toward the service hosting the resource. If any of the caches along the request path has a fresh copy of the requested representation, it uses that copy to satisfy the request. If none of the caches can satisfy the request, the request travels all the way to the service (or origin server as it is formally known).
- Client-Server – A Client is someone who is requesting resources and are not concerned with data storage, which remains internal to each server, and server is someone who holds the resources and are not concerned with the user interface or user state.
- Layered system – REST allows you to use a layered system architecture where you deploy the APIs on server A, and store data on server B and authenticate requests in Server C.
- Code on demand (optional) – servers can also provide executable code to the client. The examples of code on demand may include the compiled components such as Java applets and client-side scripts such as JavaScript.
REST Resource naming guide
We can divide resource archetypes into four categories.
- Document – A document resource is a singular concept that is akin to an object instance or database record.
Use “singular” name to denote document resource archetype.
http://api.example.com/device-management/managed-devices/{device-id}
http://api.example.com/user-management/users/id
http://api.example.com/user-management/users/admin
- Collection – A collection resource is a server-managed directory of resources. Clients may propose new resources to be added to a collection.
Use “plural” name to denote collection resource archetype.
http://api.example.com/device-management/managed-devices
http://api.example.com/user-management/users
http://api.example.com/user-management/users/{id}/accounts
- Store – A store is a client-managed resource repository. A store resource lets an API client put resources in, get them back out, and decide when to delete them. A store never generates new URIs.
Use “plural” name to denote store resource archetype.
http://api.example.com/cart-management/users/{id}/carts
http://api.example.com/song-management/users/{id}/playlists
- Controller – A controller resource models a procedural concept. Controller resources are like executable functions, with parameters and return values; inputs and outputs.
Use “verb” to denote controller archetype.
http://api.example.com/cart-management/users/{id}/cart/checkout
http://api.example.com/song-management/users/{id}/playlist/play
Best practices & rules
There are some best practices and rules which will be very useful.
- Use (/) to indicate hierarchical relationships.
http://api.example.com/device-management/managed-devices/{id}/scripts
http://api.example.com/device-management/managed-devices/{id}/scripts/{id}
- Do not use trailing forward slash (/).
http://api.example.com/device-management/managed-devices/
http://api.example.com/device-management/managed-devices /*This is much better version*/
- Use hyphens (-) instead of underscores (_).
http://api.example.com/inventory-management/managed-entities/{id}/install-script-location //More readable
http://api.example.com/inventory-management/managedEntities/{id}/installScriptLocation //Less readable
Not (_)
http://api.example.com/inventory-management/managed-entities/{id}/install-script-location //More readable
http://api.example.com/inventory_management/managed_entities/{id}/install_script_location //More error prone
- Use lower case letters in URI.
http://api.example.org/my-folder/my-doc //1
HTTP://API.EXAMPLE.ORG/my-folder/my-doc //2
http://api.example.org/My-Folder/my-doc //3
- Don’t use file extensions.
http://api.example.com/device-management/managed-devices.xml /*Do not use it*/
http://api.example.com/device-management/managed-devices /*This is correct URI*/
HATEOAS driven REST API
REST architectural style lets you use hypermedia links in the response contents so that the client can dynamically navigate to the appropriate resource by traversing the hypermedia links. Above is conceptually the same as a web user browsing through web pages by clicking the relevant hyperlinks to achieve a final goal.
For example HTTP GET http://api.domain.com/management/departments/10
{
"departmentId": 10,
"departmentName": "Administration",
"locationId": 1700,
"managerId": 200,
"links": [
{
"href": "10/employees",
"rel": "employees",
"type" : "GET"
}
]
}
In the preceding example, the response returned by the server contains hypermedia links to employee resources 10/employees, which can be traversed by the client to read employees belonging to the department.
Idempotent REST API
When making multiple identical requests has the same effect as making a single request – then that REST API is called idempotent. Except POST everything is idempotent, because POST will create a new resource N times if you invoke it N times.
Best practices to Secure REST API
- Always use HTTPS.
- Use password hash.
- Never expose information on URL.
Usernames, passwords, session tokens, and API keys should not appear in the URL, as this can be captured in web server logs, which makes them easily exploitable.
https://api.domain.com/user-management/users/{id}/someAction?apiKey=abcd123456789 //Very BAD !!
- Use OAuth instead of basic auth.
- Add timestamp in request it will prevent the basic reply attack from people who are trying brute force to your system.
Application state vs Resource state
- Application state : Application state is server-side data which servers store to identify incoming client requests, their previous interaction details, and current context information.
- Resource state : Resource state is the current state of a resource on a server at any point of time – and it has nothing to do with the interaction between client and server. It is what you get as a response from the server as API response. You refer to it as resource representation.
Advantages of statelessness
- Statelessness helps in scaling the APIs to millions of concurrent users by deploying it to multiple servers. Any server can handle any request because there is no session related dependency.
- No server side synchronization.
- Easy to cache.
- The server never loses track of “where” each client is in the application because the client sends all necessary information with each request.