Showing posts with label REST. Show all posts
Showing posts with label REST. Show all posts

Tuesday, November 12, 2019

REST 19 HTTP Status Codes

REST APIs use the Status-Line part of an HTTP response message to inform clients of their request’s overarching result. RFC 2616 defines the Status-Line syntax as shown below:

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
HTTP defines forty standard status codes that can be used to convey the results of a client’s request. The status codes are divided into the five categories presented below.

CATEGORY DESCRIPTION
1xx: Informational Communicates transfer protocol-level information.
2xx: Success Indicates that the client’s request was accepted successfully.
3xx: Redirection Indicates that the client must take some additional action in order to complete their request.
4xx: Client Error This category of error status codes points the finger at clients.
5xx: Server Error The server takes responsibility for these error status codes.
Now look at subset of codes that specially apply to the design of a REST APIs – in some more detail.


200 (OK)
It indicates that the REST API successfully carried out whatever action the client requested, and that no more specific code in the 2xx series is appropriate.

Unlike the 204 status code, a 200 response should include a response body.The information returned with the response is dependent on the method used in the request, for example:

GET an entity corresponding to the requested resource is sent in the response;
HEAD the entity-header fields corresponding to the requested resource are sent in the response without any message-body;
POST an entity describing or containing the result of the action;
TRACE an entity containing the request message as received by the end server.

201 (Created)
A REST API responds with the 201 status code whenever a resource is created inside a collection. There may also be times when a new resource is created as a result of some controller action, in which case 201 would also be an appropriate response.

The newly created resource can be referenced by the URI(s) returned in the entity of the response, with the most specific URI for the resource given by a Location header field.

The origin server MUST create the resource before returning the 201 status code. If the action cannot be carried out immediately, the server SHOULD respond with 202 (Accepted) response instead.


202 (Accepted)
A 202 response is typically used for actions that take a long while to process. It indicates that the request has been accepted for processing, but the processing has not been completed. The request might or might not be eventually acted upon, or even maybe disallowed when processing occurs.

Its purpose is to allow a server to accept a request for some other process (perhaps a batch-oriented process that is only run once per day) without requiring that the user agent’s connection to the server persist until the process is completed.

The entity returned with this response SHOULD include an indication of the request’s current status and either a pointer to a status monitor (job queue location) or some estimate of when the user can expect the request to be fulfilled.


204 (No Content)
The 204 status code is usually sent out in response to a PUT, POST, or DELETE request when the REST API declines to send back any status message or representation in the response message’s body.

An API may also send 204 in conjunction with a GET request to indicate that the requested resource exists, but has no state representation to include in the body.

If the client is a user agent, it SHOULD NOT change its document view from that which caused the request to be sent. This response is primarily intended to allow input for actions to take place without causing a change to the user agent’s active document view, although any new or updated metainformation SHOULD be applied to the document currently in the user agent’s active view.

The 204 response MUST NOT include a message-body and thus is always terminated by the first empty line after the header fields.


301 (Moved Permanently)
The 301 status code indicates that the REST API’s resource model has been significantly redesigned and a new permanent URI has been assigned to the client’s requested resource. The REST API should specify the new URI in the response’s Location header and all future requests should be directed to the given URI.

You will hardly use this response code in your API as you can always use the API versioning for new API while retaining the old one.


302 (Found)
The HTTP response status code 302 Found is a common way of performing URL redirection. An HTTP response with this status code will additionally provide a URL in the location header field. The user agent (e.g. a web browser) is invited by a response with this code to make a second, otherwise identical, request to the new URL specified in the location field.

Many web browsers implemented this code in a manner that violated this standard, changing the request type of the new request to GET, regardless of the type employed in the original request (e.g. POST). RFC 1945 and RFC 2068 specify that the client is not allowed to change the method on the redirected request. The status codes 303 and 307 have been added for servers that wish to make unambiguously clear which kind of reaction is expected of the client.


303 (See Other)
A 303 response indicates that a controller resource has finished its work, but instead of sending a potentially unwanted response body, it sends the client the URI of a response resource. This can be the URI of a temporary status message, or the URI to some already existing, more permanent, resource.

Generally speaking, the 303 status code allows a REST API to send a reference to a resource without forcing the client to download its state. Instead, the client may send a GET request to the value of the Location header.

The 303 response MUST NOT be cached, but the response to the second (redirected) request might be cacheable.


304 (Not Modified)
This status code is similar to 204 (“No Content”) in that the response body must be empty. The key distinction is that 204 is used when there is nothing to send in the body, whereas 304 is used when the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match.

In such case, there is no need to retransmit the resource since the client still has a previously-downloaded copy.

Using this saves bandwidth and reprocessing on both the server and client, as only the header data must be sent and received in comparison to the entirety of the page being re-processed by the server, then sent again using more bandwidth of the server and client.


307 (Temporary Redirect)
A 307 response indicates that the REST API is not going to process the client’s request. Instead, the client should resubmit the request to the URI specified by the response message’s Location header. However, future requests should still use the original URI.

A REST API can use this status code to assign a temporary URI to the client’s requested resource. For example, a 307 response can be used to shift a client request over to another host.

The temporary URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s). If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.


400 (Bad Request)
400 is the generic client-side error status, used when no other 4xx error code is appropriate. Errors can be like malformed request syntax, invalid request message parameters, or deceptive request routing etc.

The client SHOULD NOT repeat the request without modifications.


401 (Unauthorized)
A 401 error response indicates that the client tried to operate on a protected resource without providing the proper authorization. It may have provided the wrong credentials or none at all. The response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource.

The client MAY repeat the request with a suitable Authorization header field. If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity might include relevant diagnostic information.


403 (Forbidden)
A 403 error response indicates that the client’s request is formed correctly, but the REST API refuses to honor it i.e. the user does not have the necessary permissions for the resource. A 403 response is not a case of insufficient client credentials; that would be 401 (“Unauthorized”).

Authentication will not help and the request SHOULD NOT be repeated. Unlike a 401 Unauthorized response, authenticating will make no difference.


404 (Not Found)
The 404 error status code indicates that the REST API can’t map the client’s URI to a resource but may be available in the future. Subsequent requests by the client are permissible.

No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.


405 (Method Not Allowed)
The API responds with a 405 error to indicate that the client tried to use an HTTP method that the resource does not allow. For instance, a read-only resource could support only GET and HEAD, while a controller resource might allow GET and POST, but not PUT or DELETE.

A 405 response must include the Allow header, which lists the HTTP methods that the resource supports. For example:

Allow: GET, POST

406 (Not Acceptable)
The 406 error response indicates that the API is not able to generate any of the client’s preferred media types, as indicated by the Accept request header. For example, a client request for data formatted as application/xml will receive a 406 response if the API is only willing to format data as application/json.

If the response could be unacceptable, a user agent SHOULD temporarily stop receipt of more data and query the user for a decision on further actions.


412 (Precondition Failed)
The 412 error response indicates that the client specified one or more preconditions in its request headers, effectively telling the REST API to carry out its request only if certain conditions were met. A 412 response indicates that those conditions were not met, so instead of carrying out the request, the API sends this status code.


415 (Unsupported Media Type)
The 415 error response indicates that the API is not able to process the client’s supplied media type, as indicated by the Content-Type request header. For example, a client request including data formatted as application/xml will receive a 415 response if the API is only willing to process data formatted as application/json.

For example, the client uploads an image as image/svg+xml, but the server requires that images use a different format.


500 (Internal Server Error)
500 is the generic REST API error response. Most web frameworks automatically respond with this response status code whenever they execute some request handler code that raises an exception.

A 500 error is never the client’s fault and therefore it is reasonable for the client to retry the exact same request that triggered this response, and hope to get a different response.

API response is the generic error message, given when an unexpected condition was encountered and no more specific message is suitable.


501 (Not Implemented)
The server either does not recognize the request method, or it lacks the ability to fulfill the request. Usually, this implies future availability (e.g., a new feature of a web-service API).

REST 18 Richardson Maturity Model

Richardson Maturity Model
Leonard Richardson analyzed a hundred different web service designs and divided them into four categories based on how much they are REST compliant. This model of division of REST services to identify their maturity level – is called Richardson Maturity Model.

Richardson used three factors to decide the maturity of a service i.e. URI, HTTP Methods and HATEOAS (Hypermedia). The more a service employs these technologies – more mature it shall be considered.

The levels of maturity according to Richardson’s model
The levels of maturity according to Richardson’s model

The levels of maturity according to Richardson’s model

In this analysis, Richardson described these maturity levels as below:

Level Zero
Level One
Level Two
Level Three
Richardson Maturity Model
Richardson Maturity Model


Richardson Maturity Model

Level Zero
Level zero of maturity does not make use of any of URI, HTTP Methods, and HATEOAS capabilities.

These services have a single URI and use a single HTTP method (typically POST). For example, most Web Services (WS-*)-based services use a single URI to identify an endpoint, and HTTP POST to transfer SOAP-based payloads, effectively ignoring the rest of the HTTP verbs.

Similarly, XML-RPC based services which send data as Plain Old XML (POX). These are the most primitive way of building SOA applications with a single POST method and using XML to communicate between services.


Level One
Level one of maturity makes use of URIs out of URI, HTTP Methods, and HATEOAS.

These services employ many URIs but only a single HTTP verb – generally HTTP POST. They give each individual resource in their universe a URI. Every resource is separately identified by a unique URI – and that makes them better than level zero.


Level Two
Level two of maturity makes use of URIs and HTTP out of URI, HTTP Methods, and HATEOAS.

Level two services host numerous URI-addressable resources. Such services support several of the HTTP verbs on each exposed resource – Create, Read, Update and Delete (CRUD) services. Here the state of resources, typically representing business entities, can be manipulated over the network.

Here service designer expects people to put some effort into mastering the APIs – generally by reading the supplied documentation.

Level 2 is the good use-case of REST principles, which advocate using different verbs based on the HTTP request methods and the system can have multiple resources.


Level Three
Level three of maturity makes use of all three i.e. URIs and HTTP and HATEOAS.

This is the most mature level of Richardson’s model which encourages easy discoverability and makes it easy for the responses to be self-explanatory by using HATEOAS.

The service leads consumers through a trail of resources, causing application state transitions as a result.

REST 17 HTTP Methods

RESTful APIs enable you to develop any kind of web application having all possible CRUD (create, retrieve, update, delete) operations. REST guidelines suggest using a specific HTTP method on a specific type of call made to the server (though technically it is possible to violate this guideline, yet it is highly discouraged).

Use below-given information to find suitable HTTP method for the action performed by API.

Table of Contents

HTTP GET
HTTP POST
HTTP PUT
HTTP DELETE
HTTP PATCH
Summary
Glossary

HTTP GET
Use GET requests to retrieve resource representation/information only – and not to modify it in any way. As GET requests do not change the state of the resource, these are said to be safe methods. Additionally, GET APIs should be idempotent, which means that making multiple identical requests must produce the same result every time until another API (POST or PUT) has changed the state of the resource on the server.

If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process.

For any given HTTP GET API, if the resource is found on the server then it must return HTTP response code 200 (OK) – along with response body which is usually either XML or JSON content (due to their platform independent nature).

In case resource is NOT found on server then it must return HTTP response code 404 (NOT FOUND). Similarly, if it is determined that GET request itself is not correctly formed then server will return HTTP response code 400 (BAD REQUEST).

Example request URIs
HTTP GET http://www.appdomain.com/users
HTTP GET http://www.appdomain.com/users?size=20&page=5
HTTP GET http://www.appdomain.com/users/123
HTTP GET http://www.appdomain.com/users/123/address

HTTP POST
Use POST APIs to create new subordinate resources, e.g. a file is subordinate to a directory containing it or a row is subordinate to a database table. Talking strictly in terms of REST, POST methods are used to create a new resource into the collection of resources.

Ideally, if a resource has been created on the origin server, the response SHOULD be HTTP response code 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header.

Many times, the action performed by the POST method might not result in a resource that can be identified by a URI. In this case, either HTTP response code 200 (OK) or 204 (No Content) is the appropriate response status.

Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields.

Please note that POST is neither safe nor idempotent and invoking two identical POST requests will result in two different resources containing the same information (except resource ids).

Example request URIs
HTTP POST http://www.appdomain.com/users
HTTP POST http://www.appdomain.com/users/123/accounts

HTTP PUT
Use PUT APIs primarily to update existing resource (if the resource does not exist then API may decide to create a new resource or not). If a new resource has been created by the PUT API, the origin server MUST inform the user agent via the HTTP response code 201 (Created) response and if an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request.

If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.

The difference between the POST and PUT APIs can be observed in request URIs. POST requests are made on resource collections whereas PUT requests are made on an individual resource.
Example request URIs
HTTP PUT http://www.appdomain.com/users/123
HTTP PUT http://www.appdomain.com/users/123/accounts/456

HTTP DELETE
As the name applies, DELETE APIs are used to delete resources (identified by the Request-URI).

A successful response of DELETE requests SHOULD be HTTP response code 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has been queued, or 204 (No Content) if the action has been performed but the response does not include an entity.

DELETE operations are idempotent. If you DELETE a resource, it’s removed from the collection of resource. Repeatedly calling DELETE API on that resource will not change the outcome – however calling DELETE on a resource a second time will return a 404 (NOT FOUND) since it was already removed. Some may argue that it makes DELETE method non-idempotent. It’s a matter of discussion and personal opinion.

If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.

Example request URIs
HTTP DELETE http://www.appdomain.com/users/123
HTTP DELETE http://www.appdomain.com/users/123/accounts/456

HTTP PATCH
HTTP PATCH requests are to make partial update on a resource. If you see PUT requests also modify a resource entity so to make more clear – PATCH method is the correct choice for partially updating an existing resource and PUT should only be used if you’re replacing a resource in its entirety.

Please note that there are some challenges if you decide to use PATCH APIs in your application:

Support for PATCH in browsers, servers, and web application frameworks is not universal. IE8, PHP, Tomcat, Django, and lots of other software has missing or broken support for it.
Request payload of PATCH request is not straightforward as it is for PUT request. e.g.
HTTP GET /users/1

produces below response:

{id: 1, username: 'admin', email: 'email@example.org'}

A sample patch request to update the email will be like this:

HTTP PATCH /users/1

[
{ “op”: “replace”, “path”: “/email”, “value”: “new.email@example.org” }
]
There may be following possible operations are per HTTP specification.

[
{ "op": "test", "path": "/a/b/c", "value": "foo" },
{ "op": "remove", "path": "/a/b/c" },
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
{ "op": "replace", "path": "/a/b/c", "value": 42 },
{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
{ "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
]

PATCH method is not a replacement for the POST or PUT methods. It applies a delta (diff) rather than replacing the entire resource.


Summary of HTTP Methods for RESTful APIs
Below table summarises the use of HTTP methods discussed above.

HTTP METHOD
CRUD
ENTIRE COLLECTION (E.G. /USERS)
SPECIFIC ITEM (E.G. /USERS/123)
POST
Create
201 (Created), ‘Location’ header with link to /users/{id} containing new ID.
Avoid using POST on single resource
GET
Read
200 (OK), list of users. Use pagination, sorting and filtering to navigate big lists.
200 (OK), single user. 404 (Not Found), if ID not found or invalid.
PUT
Update/Replace
404 (Not Found), unless you want to update every resource in the entire collection of resource.
200 (OK) or 204 (No Content). Use 404 (Not Found), if ID not found or invalid.
PATCH
Partial Update/Modify
404 (Not Found), unless you want to modify the collection itself.
200 (OK) or 204 (No Content). Use 404 (Not Found), if ID not found or invalid.
DELETE
Delete
404 (Not Found), unless you want to delete the whole collection — use with caution.
200 (OK). 404 (Not Found), if ID not found or invalid.

Glossary
Safe Methods
As per HTTP specification, the GET and HEAD methods should be used only for retrieval of resource representations – and they do not update/delete the resource on the server. Both methods are said to be considered “safe“.

This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested – and they can update/delete the resource on server and so should be used carefully.

Idempotent Methods
The term idempotent is used more comprehensively to describe an operation that will produce the same results if executed once or multiple times. This is a very useful property in many situations, as it means that an operation can be repeated or retried as often as necessary without causing unintended effects. With non-idempotent operations, the algorithm may have to keep track of whether the operation was already performed or not.

In HTTP specification, The methods GET, HEAD, PUT and DELETE are declared idempotent methods. Other methods OPTIONS and TRACE SHOULD NOT have side effects so both are also inherently idempotent.

REST 16 ‘q’ Parameter in HTTP ‘Accept’ Header

A REST API can return the resource representation in many formats – to be more specific MIME-types. A client application or browser can request for any supported MIME type in HTTP Accept header. Technically, Accept header can have multiple values in form of comma separated values.

For example, an Accept header requesting for text/html or application/xml formats can be set as:

Accept : text/html,application/xml
The ‘q’ Parameter
Sometimes client may want to set their preferences when requesting multiple MIME types. To set this preference, q parameter (relative quality factor) is used.

Value of q parameter can be from 0 to 1. 0 is lowest value (i.e. least preferred) and 1 is highest (i.e. most preferred).

A sample usage can be:

Accept : text/html, application/xml;q=0.9, */*;q=0.8
In above example, client is indicating the server that it will prefer to have the response in text/html format, first. It server does not support text/html format for requested resource than it shall send application/xml format. If none of both formats are available, then send the response in whatever format it support (*/*).

One of the benefit of ‘q’ parameter is to minimize the client-server interactions, which could have happened due to failed content negotiations.
It also allows clients to receive content types of which they may not be aware, an asterisk “*” may be used in place of either the second half of MIME type value or both halves.
Here’s how the HTTP spec defines it:

Each media-range MAY be followed by one or more accept-params, beginning with the “q” parameter for indicating a relative quality factor. The first “q” parameter (if any) separates the media-range parameter(s) from the accept-params. Quality factors allow the user or user agent to indicate the relative degree of preference for that media-range, using the ‘q’ value scale from 0 to 1. The default value is 1.
If there are two MIME types for given same q value, then more specific type, between both, wins.

For example if both application/xml and */* had a preference of 0.9 then application/xml will be served by the server.

If no Accept header field is present, then it is assumed that the client accepts all media types. If an Accept header field is present, and if the server cannot send a response which is acceptable according to the combined Accept field value, then the server SHOULD send a 406 (not acceptable) response.

REST 15 N+1 Problem

N+1 problem is mostly talked in context of ORMs. In this problem, the system needs to load N children of a parent entity where only parent entity was requested for. By default, ORMs are configured with lazy-loading enabled, so 1 query issued for the parent entity causes N more queries i.e. one each for N child entities.

This N+1 problem is often considered a major performance bottleneck and so shall be solved at the design level of application.

N+1 Problem in REST APIs
Though mostly directly associated, yet the N+1 problem is not specific to ORMs only. This can be associated with the context of web APIs as well e.g. REST APIs.

In case of web APIs, N+1 problem is a situation where client applications are required to call the server N+1 times to fetch 1 collection resource + N client resources, mostly because of collection resource not had enough information about child resources to build its user interface completely.

For example, a REST API returning a collection of books as a resource.

<books uri="/books" size="100">
    <book uri="/books/1" id="1">
        <isbn>3434253561</isbn>
    </book>
    <book uri="/books/2" id="2">
        <isbn>3423423534</isbn>
    </book>
    <book uri="/books/3" id="3">
        <isbn>5352342344</isbn>
    </book>
    ...
    ...
</books>
Here /books resource return list of books with information including only it’s id and isbn. This information is clearly not enough to build a client application UI which will want to typically show the books name in UI rather than ISBN. It may be that they want to show other information such as author and publication year as well.

In above scenario, client application MUST make N more requests for each individual book resource at /books/{id}. So in the total client will end up invoking REST APIs N+1 times.

Above scenario is only for example. Idea is that insufficient information in collection resources may lead to N+1 problem in REST APIs.

How to Solve N+1 Problem
The good thing about the previously discussed problem is that we know what exactly is the issue. And this makes the solution pretty easy. Include more information in individual resources inside collection resource.

You may consult with API consumers, do market research for similar applications and their user interfaces or simply put yourself in the client’s shoe.

Moreover, you may evolve your APIs over the time as your understanding around client requirements improve. This is possible using API versioning.

REST 14 PUT vs POST

It has been observed that many people struggle to choose between HTTP PUT vs POST methods when designing a system. Though, RFC 2616 has been very clear in differentiating between the two – yet complex wordings are a source of confusion for many of us. Let’s try to solve the puzzle when to use PUT or POST.

Let’s compare them for better understanding.

PUT POST
RFC-2616 clearly mention that PUT method requests for the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource – an update operation will happen, otherwise create operation should happen if Request-URI is a valid resource URI (assuming client is allowed to determine resource identifier).
PUT /questions/{question-id}
The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. It essentially means that POST request-URI should be of a collection URI.
POST /questions
PUT method is idempotent. So if you send retry a request multiple times, that should be equivalent to single request modification. POST is NOT idempotent. So if you retry the request N times, you will end up having N resources with N different URIs created on server.
Use PUT when you want to modify a singular resource which is already a part of resources collection. PUT replaces the resource in its entirety. Use PATCH if request updates part of the resource. Use POST when you want to add a child resource under resources collection.
Though PUT is idempotent, we shall not cache it’s response. Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields. However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource.
Generally, in practice, always use PUT for UPDATE operations. Always use POST for CREATE operations.
PUT vs POST : An Example
Let’s say we are designing a network application. Let’s list down few URIs and their purpose to get better understanding when to use POST and when to use PUT operations.

GET /device-management/devices : Get all devices
POST /device-management/devices : Create a new device

GET /device-management/devices/{id} : Get the device information identified by "id"
PUT /device-management/devices/{id} : Update the device information identified by "id"
DELETE /device-management/devices/{id} : Delete device by "id"
Follow the similar URI design practices for other resources as well.

REST - Part 13 Create REST APIs with JAX-RS 2.0

 In this post, we will learn to create REST APIs using JAX-RS 2.0 (Java API for RESTful Services).

Table of Contents

JAX-RS 2.0 Specification
JAX-RS 2.0 Annotations
Create Maven Application
Include JAX-RS Dependencies to Application
Create Resource Representations
Create REST Resource
Register Resource in runtime
Demo

JAX-RS 2.0 Specification
JAX-RS provides portable APIs for developing, exposing and accessing Web applications designed and implemented in compliance with principles of REST architectural style.

The Java EE 6 release took the first step towards standardizing RESTful web service APIs by introducing a Java API for RESTful web services (JAX-RS) [JSR 311]. JAX-RS ensures portability of REST API code across all Java EE-compliant application servers. The latest version is JAX-RS 2.0 [JSR 339], which was released as part of the Java EE 7 platform.

JAX-RS focuses on applying Java annotations to plain Java objects. JAX-RS has annotations to bind specific URI patterns and HTTP operations to individual methods of your Java class. It also has annotations which can help you handle in input/output parameters.

As we already said that JAX-RS is specification; it means we need to have its implementation to run REST API code. Some of the popular JAX-RS implementations available today are:

Jersey
RESTEasy
Apache CXF
Restlet


JAX-RS 2.0 Annotations 

https://restfulapi.net/create-rest-apis-with-jax-rs-2-0/

REST - Part 12 How to design a REST API

Steps in designing REST Services
Identify Object Model
Create Model URIs
Determine Representations
Assign HTTP Methods
More Actions

Identify Object Model
The very first step in designing a REST API based application is – identifying the objects which will be presented as resources.

For a network based application, object modeling is pretty much simpler. There can be many things such as devices, managed entities, routers, modems etc. For simplicity sake, we will consider only two resources i.e.

Devices
Configurations
Here configuration is sub-resource of a device. A device can have many configuration options.

Note that both objects/resources in our above model will have a unique identifier, which is the integer id property.


Create Model URIs
Now when object model is ready, it’s time to decide the resource URIs. At this step, while designing the resource URIs – focus on the relationship between resources and its sub-resources. These resource URIs are endpoints for RESTful services.

In our application, a device is a top-level resource. And configuration is sub-resource under device. Let’s write down the URIs.

/devices
/devices/{id}

/configurations
/configurations/{id}

/devices/{id}/configurations
/devices/{id}/configurations/{id}
Notice that these URIs do not use any verb or operation. It’s very important to not include any verb in URIs. URIs should all be nouns only.


Determine Representations
Now when resource URIs have been decided, let’s work on their representations. Mostly representations are defined in either XML or JSON format. We will see XML examples as its more expressive on how data is composed.

Collection of Device Resource
When returning a collection resource, include only most important information about resource. This will keep the size of payload small, and so will improve the performance of REST APIs.

<devices size="2">

    <link rel="self" href="/devices"/>

    <device id="12345">
        <link rel="self" href="/devices/12345"/>
        <deviceFamily>apple-es</deviceFamily>
        <OSVersion>10.3R2.11</OSVersion>
        <platform>SRX100B</platform>
        <serialNumber>32423457</serialNumber>
        <connectionStatus>up</connectionStatus>
        <ipAddr>192.168.21.9</ipAddr>
        <name>apple-srx_200</name>
        <status>active</status>
    </device>

    <device id="556677">
        <link rel="self" href="/devices/556677"/>
        <deviceFamily>apple-es</deviceFamily>
        <OSVersion>10.3R2.11</OSVersion>
        <platform>SRX100B</platform>
        <serialNumber>6453534</serialNumber>
        <connectionStatus>up</connectionStatus>
        <ipAddr>192.168.20.23</ipAddr>
        <name>apple-srx_200</name>
        <status>active</status>
    </device>

</devices>
Single Device Resource
Opposite to collection URI, here include complete information of a device in this URI. Here, also include a list of links for sub-resources and other supported operations. This will make your REST API HATEOAS driven.

<device id="12345">
    <link rel="self" href="/devices/12345"/>

    <id>12345</id>
    <deviceFamily>apple-es</deviceFamily>
    <OSVersion>10.0R2.10</OSVersion>
    <platform>SRX100-LM</platform>
    <serialNumber>32423457</serialNumber>
    <name>apple-srx_100_lehar</name>
    <hostName>apple-srx_100_lehar</hostName>
    <ipAddr>192.168.21.9</ipAddr>
    <status>active</status>

    <configurations size="2">
        <link rel="self" href="/configurations" />

        <configuration id="42342">
            <link rel="self" href="/configurations/42342" />
        </configuration>

        <configuration id="675675">
            <link rel="self" href="/configurations/675675" />
        </configuration>
    </configurations>

    <method href="/devices/12345/exec-rpc" rel="rpc"/>
    <method href="/devices/12345/synch-config"rel="synch device configuration"/>
</device>
Configuration Resource Collection
Similar to device collection representation, create configuration collection representation with only minimal information.

<configurations size="20">
    <link rel="self" href="/configurations" />

    <configuration id="42342">
        <link rel="self" href="/configurations/42342" />
    </configuration>

    <configuration id="675675">
        <link rel="self" href="/configurations/675675" />
    </configuration>
    ...
    ...
</configurations>
Please note that configurations collection representation inside device is similar to top-level configurations URI. Only difference is that configurations for a device are only two, so only two configuration items are listed as subresource under device.

Single Configuration Resource
Now, single configuration resource representation must have all possible information about this resource – including relevant links.

<configuration id="42342">
    <link rel="self" href="/configurations/42342" />
    <content><![CDATA[...]]></content>
    <status>active</status>
    <link  rel="raw configuration content" href="/configurations/42342/raw" />
</configuration>
Configuration Resource Collection Under Single Device
This resource collection of configurations will be a subset of primary collection of configurations, and will be specific a device only. As it is the subset of primary collection, DO NOT create a different representation data fields than primary collection. Use same presentation fields as primary collection.

<configurations size="2">
    <link rel="self" href="/devices/12345/configurations" />

    <configuration id="53324">
        <link rel="self" href="/devices/12345/configurations/53324" />
        <link rel="detail" href="/configurations/53324" />
    </configuration>

    <configuration id="333443">
        <link rel="self" href="/devices/12345/configurations/333443" />
        <link rel="detail" href="/configurations/333443" />
    </configuration>
</configurations>
Notice that this subresource collection has two links. One for its direct representation inside sub-collection i.e. /devices/12345/configurations/333443 and other pointing to its location in primary collection i.e. /configurations/333443.

Having two links is important as you can provide access to a device specific configuration in more unique manner, and you will have ability to mask some fields (if design require it) which shall not be visible in a secondary collection.

Single Configuration Resource Under Single Device
This representation should have either exactly similar representation as of Configuration representation from primary collection; OR you may mask few fields.

This subresource representation will also have an additional link to its primary presentation.

<configuration id="11223344">
    <link rel="self" href="/devices/12345/configurations/11223344" />
    <link rel="detail" href="/configurations/11223344" />
    <content><![CDATA[...]]></content>
    <status>active</status>
    <link rel="raw configuration content" href="/configurations/11223344/raw" />
</configuration>
Now, before moving forward to next section, let’s note down few observations so you don’t miss them.

Resource URIs are all nouns.
URIs are usually in two forms – collection of resources and singular resource.
Collection may be in two forms primary collection and secondary collection. Secondary collection is sub-collection from a primary collection only.
Each resource/collection contain at least one link i.e. to itself.
Collections contain only most important information about resources.
To get complete information about a resource, you need to access through its specific resource URI only.
Representations can have extra links (i.e. methods in single device). Here method represent a POST method. You can have more attributes or form links in altogether new way also.
We have not talked about operations on these resources yet.

Assign HTTP Methods
So our resource URIs and their representation are fixed now. Let’s decide the possible operations in application and map these operations on resource URIs. A user of network application can perform browse, create, update or delete operations. So let’s map them.

Browse all devices or configurations [Primary Collection]
HTTP GET /devices
HTTP GET /configurations
If the collection size is large, you can apply paging and filtering as well. e.g. Below requests will fetch first 20 records from collection.

HTTP GET /devices?startIndex=0&size=20
HTTP GET /configurations?startIndex=0&size=20
Browse all devices or configurations [Secondary Collection]
HTTP GET /devices/{id}/configurations
It will be mostly a small size collection – so no need to enable filtering or soring here.

Browse single device or configuration [Primary Collection]
To get the complete detail of a device or configuration, use GET operation on singular resource URIs.

HTTP GET /devices/{id}
HTTP GET /configurations/{id}
Browse single device or configuration [Secondary Collection]
HTTP GET /devices/{id}/configurations/{id}
Subresource representation will be either same as or subset of primary presentation.

Create a device or configuration
Create is not idempotent operation, and in HTTP protocol – POST is also not idempotent. So use POST.

HTTP POST /devices
HTTP POST /configurations
Please note that request payload will not contain any id attribute, as server is responsible for deciding it. Response of create request will look like this:

HTTP/1.1 201 Created
Content-Type: application/xml
Location: http://example.com/network-app/configurations/678678

<configuration id="678678">
    <link rel="self" href="/configurations/678678" />
    <content><![CDATA[...]]></content>
    <status>active</status>
    <link  rel="raw configuration content" href="/configurations/678678/raw" />
</configuration>
Update a device or configuration
Update operation is an idempotent operation and HTTP PUT is also is idempotent method. So we can use PUT method for update operations.

HTTP PUT /devices/{id}
HTTP PUT /configurations/{id}
PUT response may look like this.

HTTP/1.1 200 OK
Content-Type: application/xml

<configuration id="678678">
    <link rel="self" href="/configurations/678678" />
    <content><![CDATA[. updated content here .]]></content>
    <status>active</status>
    <link  rel="raw configuration content" href="/configurations/678678/raw" />
</configuration>
Remove a device or configuration
Removing is always a DELETE operation.

HTTP DELETE /devices/{id}
HTTP DELETE /configurations/{id}
A successful response SHOULD be 202 (Accepted) if resource has been queues for deletion (async operation), or 200 (OK) / 204 (No Content) if resource has been deleted permanently (sync operation).

In case of async operation, application shall return a task id which can be tracked for success/failure status.

Please note that you should put enough analysis in deciding the behavior when a subresource is deleted from system. Normally, you may want to SOFT DELETE a resource in these requests – in other words, set their status INACTIVE. By following this approach, you will not need to find and remove its references from other places as well.

Applying or Removing a configuration from a device
In real application, you will need to apply the configuration on device – OR you may want to remove the configuration from device (not from primary collection). You shall use PUT and DELETE methods in this case, because of its idempotent nature.

//Apply Configuration on a device
HTTP PUT /devices/{id}/configurations     

//Remove Configuration on a device 
HTTP DELETE /devices/{id}/configurations/{id}     

More Actions
So far we have designed only object model, URIs and then decided HTTP methods or operations on them. You need to work on other aspects of the application as well:

1) Logging
2) Security
3) Discovery etc.

In next article, we will create this application in java to get more detailed understanding.

REST - Part 11 Statelessness


As per the REST (REpresentational “State” Transfer) architecture, the server does not store any state about the client session on the server side. This restriction is called Statelessness. Each request from the client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client. client is responsible for storing and handling all application state related information on client side.

It also means that the client is responsible for sending any state information to the server whenever it is needed. There should not be any session affinity or sticky sessions on server.

Statelessness means that every HTTP request happens in complete isolation. When the client makes an HTTP request, it includes all information necessary for the server to fulfill that request. The server never relies on information from previous requests. If that information was important, the client would have sent it again in this request.
To enable clients to access these stateless APIs, its necessary that servers also should include every piece of information that the client may need to create the state on its side.

For becoming stateless, do not store even authentication/authorization details of client. Provide credentials with the request. Each request MUST stand alone and should not be affected by the previous conversation happened from the same client in past.

Application State vs Resource State
Please do not confuse between application state and resource state. Both are completely different things.

Application state is server-side data which servers store to identify incoming client requests, their previous interaction details, and current context information.

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.

REST statelessness means being free on application state.

Advantages of Statelessness
There are some very noticeable advantages for having REST APIs stateless.

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.
Being stateless makes REST APIs less complex – by removing all server-side state synchronization logic.
A stateless API is also easy to cache as well. A specific software can decide whether or not to cache the result of an HTTP request just by looking at that one request. There’s no nagging uncertainty that state from a previous request might affect the cacheability of this one. It improves the performance of applications.
The server never loses track of “where” each client is in the application because the client sends all necessary information with each request.

REST - Part 10 REST API Versioning

To manage this complexity, version your API. Versioning helps you iterate faster when the needed changes are identified.

Change in an API is inevitable as your knowledge and experience of a system improve. Managing the impact of this change can be quite a challenge when it threatens to break existing client integration.
When to Version
APIs only need to be up-versioned when a breaking change is made. Breaking changes include:

a change in the format of the response data for one or more calls
a change in the response type (i.e. changing an integer to a float)
removing any part of the API.
Breaking changes should always result in a change to the major version number for an API or content response type.

Non-breaking changes, such as adding new endpoints or new response parameters, do not require a change to the major version number. However, it can be helpful to track the minor versions of APIs when changes are made to support customers who may be receiving cached versions of data or may be experiencing other API issues.

How to Version
REST doesn’t provide for any specific versioning guidelines but the more commonly used approaches fall into three categories:

URI Versioning
Using the URI is the most straightforward approach (and most commonly used as well) though it does violate the principle that a URI should refer to a unique resource. You are also guaranteed to break client integration when a version is updated.

e.g.

http://api.example.com/v1
http://apiv1.example.com
The version need not be numeric, nor specified using the “v[x]” syntax. Alternatives include dates, project names, seasons or other identifiers that are meaningful enough to the team producing the APIs and flexible enough to change as the versions change.

Versioning using Custom Request Header
A custom header (e.g. Accept-version) allows you to preserve your URIs between versions though it is effectively a duplicate of the content negotiation behavior implemented by the existing Accept header.

e.g.

Accept-version: v1
Accept-version: v2
Versioning using Accept header
Content negotiation may let you preserve a clean set of URLs but you still have to deal with the complexity of serving different versions of content somewhere. This burden tends to be moved up the stack to your API controllers which become responsible for figuring out which version of a resource to send. The end result tends to be a more complex API as clients have to know which headers to specify before requesting a resource.

e.g.

Accept: application/vnd.example.v1+json
Accept: application/vnd.example+json;version=1.0
In the real world, an API is never going to be completely stable. So it’s important how this change is managed. A well documented and gradual deprecation of API can be an acceptable practice for most of the APIs.

REST - Part 9 REST API Security Essentials

REST API Security Essentials
Security isn’t an afterthought. It has to be an integral part of any development project and also for REST APIs. There are multiple ways to secure a RESTful API e.g. basic auth, OAuth etc. but one thing is sure that RESTful APIs should be stateless – so request authentication/authorization should not depend on cookies or sessions. Instead, each API request should come with some sort authentication credentials which must be validated on the server for each and every request.

REST Security Design Principles
The paper “The Protection of Information in Computer Systems” by Jerome Saltzer and Michael Schroeder, put forth eight design principles for securing information in computer systems, as described in the following sections:

Least Privilege: An entity should only have the required set of permissions to perform the actions for which they are authorized, and no more. Permissions can be added as needed and should be revoked when no longer in use.
Fail-Safe Defaults: A user’s default access level to any resource in the system should be “denied” unless they’ve been granted a “permit” explicitly.
Economy of Mechanism: The design should be as simple as possible. All the component interfaces and the interactions between them should be simple enough to understand.
Complete Mediation: A system should validate access rights to all its resources to ensure that they’re allowed and should not rely on cached permission matrix. If the access level to a given resource is being revoked, but that isn’t reflected in the permission matrix, it would violate the security.
Open Design: This principle highlights the importance of building a system in an open manner—with no secret, confidential algorithms.
Separation of Privilege: Granting permissions to an entity should not be purely based on a single condition, a combination of conditions based on the type of resource is a better idea.
Least Common Mechanism: It concerns the risk of sharing state among different components. If one can corrupt the shared state, it can then corrupt all the other components that depend on it.
Psychological Acceptability: It states that security mechanisms should not make the resource more difficult to access than if the security mechanisms were not present. In short, security should not make worse the user experience.
Best Practices to Secure REST APIs
Below given points may serve as a checklist for designing the security mechanism for REST APIs.

Keep it Simple
Secure an API/System – just how secure it needs to be. Every time you make the solution more complex “unnecessarily”, you are also likely to leave a hole.

Always Use HTTPS
By always using SSL, the authentication credentials can be simplified to a randomly generated access token that is delivered in the username field of HTTP Basic Auth. It’s relatively simple to use, and you get a lot of security features for free.

If you use HTTP 2, to improve performance – you can even send multiple requests over a single connection, that way you avoid the complete TCP and SSL handshake overhead on later requests.

Use Password Hash
Passwords must always be hashed to protect the system (or minimize the damage) even if it is compromised in some hacking attempt. There are many such hashing algorithms which can prove really effective for password security e.g. MD5, SHA, PBKDF2, bcrypt and scrypt algorithms.

Never expose information on URLs
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 !!
Above URL exposes API key So, never use this form of security.

Consider OAuth
Though basic auth is good enough for most of the APIs and if implemented correctly, it’s secure as well – yet you may want to consider OAuth as well. The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.

Consider Adding Timestamp in Request
Along with other request parameters, you may add a request timestamp as HTTP custom header in API request. The server will compare the current timestamp to the request timestamp, and only accepts the request if it is within a reasonable timeframe (1-2 minutes, perhaps).

This will prevent very basic replay attacks from people who are trying to brute force your system without changing this timestamp.

Input Parameter Validation
Validate request parameters on the very first step, before it reaches to application logic. Put strong validation checks and reject the request immediately if validation fails. In API response, send relevant error messages and example of correct input format to improve user experience.

REST - Part 8 Idempotent REST APIs

In the context of REST APIs, when making multiple identical requests has the same effect as making a single request – then that REST API is called idempotent.

When you design REST APIs, you must realize that API consumers can make mistakes. They can write client code in such a way that there can be duplicate requests as well. These duplicate requests may be unintentional as well as intentional some time (e.g. due to timeout or network issues). You have to design fault-tolerant APIs in such a way that duplicate requests do not leave the system unstable.

An idempotent HTTP method is an HTTP method that can be called many times without different outcomes. It would not matter if the method is called only once, or ten times over. The result should be the same. It essentially means that the result of a successfully performed request is independent of the number of times it is executed. For example, in arithmetic, adding zero to a number is idempotent operation.
If you follow REST principles in designing API, you will have automatically idempotent REST APIs for GET, PUT, DELETE, HEAD, OPTIONS and TRACE HTTP methods. Only POST APIs will not be idempotent.

POST is NOT idempotent.
GET, PUT, DELETE, HEAD, OPTIONS and TRACE are idempotent.
Let’s analyze how above HTTP methods end up being idempotent – any why POST is not.

HTTP POST
Generally – not necessarily – POST APIs are used to create a new resource on server. So when you invoke the same POST request N times, you will have N new resources on the server. So, POST is not idempotent.

HTTP GET, HEAD, OPTIONS and TRACE
GET, HEAD, OPTIONS and TRACE methods NEVER change the resource state on server. They are purely for retrieving the resource representation or meta data at that point of time. So invoking multiple requests will not have any write operation on server, so GET, HEAD, OPTIONS and TRACE are idempotent.

HTTP PUT
Generally – not necessarily – PUT APIs are used to update the resource state. If you invoke a PUT API N times, the very first request will update the resource; then rest N-1 requests will just overwrite the same resource state again and again – effectively not changing anything. Hence, PUT is idempotent.

HTTP DELETE
When you invoke N similar DELETE requests, first request will delete the resource and response will be 200 (OK) or 204 (No Content). Other N-1 requests will return 404 (Not Found). Clearly, the response is different from first request, but there is no change of state for any resource on server side because original resource is already deleted. So, DELETE is idempotent.

Please keep in mind if some systems may have DELETE APIs like this:

DELETE /item/last
In the above case, calling operation N times will delete N resources – hence DELETE is not idempotent in this case. In this case, a good suggestion might be to change above API to POST – because POST is not idempotent.

POST /item/last
Now, this is closer to HTTP spec – hence more REST compliant.

REST - Part 7 HATEOAS Driven REST APIs

HATEOAS (Hypermedia as the Engine of Application State) is a constraint of the REST application architecture that keeps the RESTful style architecture unique from most other network application architectures. The term “hypermedia” refers to any content that contains links to other forms of media such as images, movies, and text.

This 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. This is conceptually the same as a web user navigating through web pages by clicking the appropriate hyperlinks in order to achieve a final goal.

For example, below given JSON response may be from an API like 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.

The advantage of the above approach is that hypermedia links returned from the server drive the application’s state and not the other way around.

There is no universally accepted format for representing links between two resources in JSON. You may choose to adopt the above format or you may choose to send links in HTTP response headers.

HTTP/1.1 200 OK
...
Link: <10/employees>; rel="employees"
Both are absolutely valid solutions.

HATEOAS Implementation
In the real world, when you visit a website – you hit its homepage. It presents some snapshots and links to other sections of websites. You click on them and then you get more information along with more related links which are relevant to the context.

Similar to a human’s interaction with a website, a REST client hits an initial API URI and uses the server-provided links to dynamically discover available actions and access the resources it needs. The client need not have prior knowledge of the service or the different steps involved in a workflow. Additionally, the clients no longer have to hard code the URI structures for different resources. This allows the server to make URI changes as the API evolves without breaking the clients.

Above API interaction is possible using HATEOAS only.

Each REST framework provides it’s own way on creating the HATEOAS links using framework capabilities e.g. in this RESTEasy HATEOAS tutorial, links are part of resource model classes which is transferred as resource state to the client.

HATEOAS References
The following are the two popular formats for specifying JSON REST API hypermedia links:

RFC 5988 (web linking)
RFC 5988 puts forward a framework for building links that defines the relation between resources on the web. Each link in RFC 5988 contains the following properties:

Target URI: Each link should contain a target Internationalized Resource Identifiers (IRIs). This is represented by the href attribute.

Link relation type: The link relation type describes how the current context (source) is related to the target resource. This is represented by the rel attribute.

Attributes for target IRI: The attributes for a link include hreflang, media, title, and type, and any extension link parameters.

JSON Hypermedia API Language (HAL)
JSON HAL is a promising proposal that sets the conventions for expressing hypermedia controls, such as links, with JSON or XML. It is in the draft stage at this time.

The two associated MIME types are

media type: application/hal+xml
media type: application/hal+json
Each link in HAL may contain the following properties:

Target URI: It indicates the target resource URI. This is represented by the href attribute.
Link relation: The link relation type describes how the current context is related to the target resource. This is represented by the rel attribute.
Type: This indicates the expected resource media type. This is represented by the type attribute.

There is no right or wrong in choosing a hypermedia link format for your application. You should pick up a format that meets most of your use case requirements and stick to it.

REST - Part 6 Caching REST API Response

Generally, resources can have multiple presentations, mostly because there may be multiple different clients expecting different representations. Asking for a suitable presentation by a client, is referred as content negotiation.

HTTP has provisions for several mechanisms for “content negotiation” — the process of selecting the best representation for a given response when there are multiple representations available.
RFC 2616
Server-driven Vs Agent-driven Content Negotiation
If the selection of the best representation for a response is made by an algorithm located at the server, it is called server-driven negotiation. If that selection is made at agent or client side, its called agent-driven content negotiation.

Practically, you will NOT find much usage of server side negotiations because in that way, you have to make lots of assumptions about client expectations. Few things like client context or how client will use the resource representation is almost impossible to determine. Apart from that this approach makes the server side code complex, unnecessarily.

So, most REST API implementations rely on agent driven content negotiations. Agent driven content negotiation rely on usage of HTTP request headers or resource URI patterns.

Content negotiation using HTTP headers
At server side, an incoming request may have an entity attached to it. To determine it’s type, server uses the HTTP request header Content-Type. Some common examples of content types are “text/plain”, “application/xml”, “text/html”, “application/json”, “image/gif”, and “image/jpeg”.

Content-Type: application/json
Similarly, to determine what type of representation is desired at client side, HTTP header ACCEPT is used. It will have one of the values as mentioned for Content-Type above.

Accept: application/json
Generally, if no Accept header is present in the request, the server can send pre-configured default representation type.

Implementing Accept header based content negotiation is most used and recommened way.
Content negotiation using URL patterns
Another way to pass content type information to server, client may use specific extension in resource URIs. For example, a client can ask for details using:

http://rest.api.com/v1/employees/20423.xml
http://rest.api.com/v1/employees/20423.json
In above case, first request URI will return a XML response whether second request URI will return a JSON response.

Defining preferences
If is possible to have multiple values in Accept header. Client may want to give multiple values in accept header when client is not sure about if its desired representation is present or supported by server at that time. [RFC 2296]

For example,

Accept: application/json,application/xml;q=0.9,*/*;q=0.8

Above Accept header allows you to ask the server a JSON format. If it can’t, perhaps it could return XML format (the second level). If it’s still not possible, let it return what it can.

The preference order is defined through the q parameter with values from 0 to 1. When nothing is specified, the implicit value is 1.

REST - Part 5 Caching REST API Response

REST APIs can return the resource representations in a number of formats such as XML, JSON, HTML or even plain text. All such forms can be compressed to a lesser number of bytes to save bandwidth over the network. Different protocols use different techniques to enable compression and notify the clients about compression scheme – so that client can decompress it before consuming the representations.

Compression, like encryption, is something that happens to a representation in transit and must be undone before the client can use the representation.
HTTP is most widely used protocol for REST – so I am taking example of HTTP specific response compression.

Compression Related Request/Response Headers
Accept-Encoding
While requesting resource representations – along with an HTTP request the client sends an Accept-Encoding header that says what kind of compression algorithms the client understands.

The two standard values for Accept-Encoding are compress and gzip.

A sample request with accept-encoding header looks like this :

GET        /employees         HTTP/1.1
Host:     www.domain.com
Accept:     text/html
Accept-Encoding:     gzip,compress
Other possible usage of accept-encoding may be:

Accept-Encoding: compress, gzip
Accept-Encoding:
Accept-Encoding: *
Accept-Encoding: compress;q=0.5, gzip;q=1.0
Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0
If an Accept-Encoding field is present in a request, and if the server cannot send a response which is acceptable according to the Accept-Encoding header, then the server SHOULD send an error response with the 406 (Not Acceptable) status code.

Content-Encoding
If the server understands one of the compression algorithms from Accept-Encoding, it can use that algorithm to compress the representation before serving it. When successfully compressed, server lets know the client of encoding scheme by another HTTP header i.e. Content-Encoding.

200 OK
Content-Type:     text/html
Content-Encoding:     gzip
If the content-coding of an entity in a request message is not acceptable to the origin server, the server SHOULD respond with a status code of 415 (Unsupported Media Type). If multiple encodings have been applied to an entity, the content encodings MUST be listed in the order in which they were applied.

Please note that original media-type for request and response are not impacted whether compression is requested or not.

Compression can save a lot of bandwidth, with very little cost in additional complexity. Also, you may know that most web browsers automatically request compressed representations from website host servers – using above headers.

REST - Part 4 Caching REST API Response

Caching REST API Response
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).

Using HTTP headers, an origin server indicates whether a response can be cached and if so, by whom, and for how long. Caches along the response path can take a copy of a response, but only if the caching metadata allows them to do so.

Optimizing the network using caching improves the overall quality-of-service in following ways:

Reduce bandwidth
Reduce latency
Reduce load on servers
Hide network failures

Caching in REST APIs
Being cacheable is one of architectural constraints of REST. GET requests should be cachable by default – until special condition arises. Usually, browsers treat all GET requests cacheable. POST requests are not cacheable by default but can be made cacheable if either an Expires header or a Cache-Control header with a directive, to explicitly allows caching, is added to the response. Responses to PUT and DELETE requests are not cacheable at all.

There are two main HTTP response headers that we can use to control caching behavior:

Expires
The Expires HTTP header specifies an absolute expiry time for a cached representation. Beyond that time, a cached representation is considered stale and must be re-validated with the origin server. To indicate that a representation never expires, a service can include a time up to one year in the future.

Expires: Fri, 20 May 2016 19:20:49 IST
Cache-Control
The header value comprises one or more comma-separated directives. These directives determine whether a response is cacheable, and if so, by whom, and for how long e.g. max-age or s-maxage directives.

Cache-Control: max-age=3600
Cacheable responses (whether to a GET or to a POST request) should also include a validator — either an ETag or a Last-Modified header.

ETag
An ETag value is an opaque string token that a server associates with a resource to uniquely identify the state of the resource over its lifetime. When the resource changes, the ETag changes accordingly.

ETag: "abcd1234567n34jv"

Last-Modified
Whereas a response’s Date header indicates when the response was generated, the Last-Modified header indicates when the associated resource last changed. The Last-Modified value cannot be less than the Date value.

Last-Modified: Fri, 10 May 2016 09:17:49 IST

REST - Part 3 REST Resource Naming Guide

In REST, primary data representation is called Resource.A resource can be a singleton or a collection. For example, “customers” is a collection resource and “customer” is a singleton resource (in a banking domain). We can identify “customers” collection resource using the URI “/customers”. We can identify a single “customer” resource using the URI “/customers/{customerId}”.

A resource may contain sub-collection resources also. For example, sub-collection resource “accounts” of a particular “customer” can be identified using the URN “/customers/{customerId}/accounts” (in a banking domain). Similarly, a singleton resource “account” inside the sub-collection resource “accounts” can be identified as follows: “/customers/{customerId}/accounts/{accountId}”.

REST APIs use Uniform Resource Identifiers (URIs) to address resources. REST API designers should create URIs that convey a REST API’s resource model to its potential client developers. When resources are named well, an API is intuitive and easy to use. If done poorly, that same API can feel difficult to use and understand.

The constraint of uniform interface is partially addressed by the combination of URIs and HTTP verbs and using them in line with the standards and conventions.

Below are a few tips to get you going when creating the resource URIs for your new API.

Resource Archetypes


A REST API is composed of 4 distinct resource archetypes: document, collection, store and controller. In order to communicate a clear and clean resource model to its clients, a REST API should align each resource with only 1 of these archetypes

document
A document resource is a singular concept that is akin to an object instance or database record. In REST, you can view it as a single resource inside resource collection. A document’s state representation typically includes both fields with values and links to other related resources.

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. However, it is up to the collection to choose to create a new resource, or not. A collection resource chooses what it wants to contain and also decides the URIs of each contained resource.

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. Instead, each stored resource has a URI that was chosen by a client when it was initially put into the store.

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

REST Resource Naming Best Practices

Use nouns to represent resources

Use nouns to represent resources
RESTful URI should refer to a resource that is a thing (noun) instead of referring to an action (verb) because nouns have properties which verbs do not have – similar to resources have attributes. Some examples of a resource are:

Users of the system
User Accounts
Network Devices etc.
and their resource URIs can be designed as below:

http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices/{device-id}
http://api.example.com/user-management/users/
http://api.example.com/user-management/users/{id}

Consistency is the key

Use forward slash (/) to indicate a hierarchical relationships
The forward slash (/) character is used in the path portion of the URI to indicate a hierarchical relationship between resources. e.g.

http://api.example.com/device-management
http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices/{id}
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 (/) in URIs
As the last character within a URI’s path, a forward slash (/) adds no semantic value and may cause confusion. It’s better to drop them completely.

http://api.example.com/device-management/managed-devices/
http://api.example.com/device-management/managed-devices /*This is much better version*/

Use hyphens (-) to improve the readability of URIs
To make your URIs easy for people to scan and interpret, use the hyphen (-) character to improve the readability of names in long path segments.

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

Do not use underscores ( _ )
It’s possible to use an underscore in place of a hyphen to be used as separator – But depending on the application’s font, it’s possible that the underscore (_) character can either get partially obscured or completely hidden in some browsers or screens.

To avoid this confusion, 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/managed_entities/{id}/install_script_location  //More error prone

Use lowercase letters in URIs
When convenient, lowercase letters should be consistently preferred in URI paths.

RFC 3986 defines URIs as case-sensitive except for the scheme and host components. e.g.

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
In above examples, 1 and 2 are same but 3 is not as it uses My-Folder in capital letters.

Do not use file extenstions
File extensions look bad and do not add any advantage. Removing them decrease the length of URIs as well. No reason to keep them.

Apart from above reason, if you want to highlight the media type of API using file extenstion then you should rely on the media type, as communicated through the Content-Type header, to determine how to process the body’s content.

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*/

Never use CRUD function names in URIs
URIs should not be used to indicate that a CRUD function is performed. URIs should be used to uniquely identify resources and not any action upon them. HTTP request methods should be used to indicate which CRUD function is performed.

HTTP GET http://api.example.com/device-management/managed-devices  //Get all devices
HTTP POST http://api.example.com/device-management/managed-devices  //Create new Device

HTTP GET http://api.example.com/device-management/managed-devices/{id}  //Get device for given Id
HTTP PUT http://api.example.com/device-management/managed-devices/{id}  //Update device for given Id
HTTP DELETE http://api.example.com/device-management/managed-devices/{id}  //Delete device for given Id

Use query component to filter URI collection
Many times, you will come across requirements where you will need a collection of resources sorted, filtered or limited based on some certain resource attribute. For this, do not create new APIs – rather enable sorting, filtering and pagination capabilities in resource collection API and pass the input parameters as query parameters. e.g.

http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices?region=USA
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ&sort=installation-date

Monday, November 11, 2019

REST - Part 2 REST Architectural Constraints

REST defines 6 architectural constraints which make any web service – a true RESTful API.

Uniform interface
Client–server
Stateless
Cacheable
Layered system
Code on demand (optional)

Uniform interface
Once a developer becomes familiar with one of your API, he should be able to follow the similar approach for other APIs.

Client–server
This essentially means that client application and server application MUST be able to evolve separately without any dependency on each other. A client should know only resource URIs and that’s all.

Stateless
Roy fielding got inspiration from HTTP, so it reflects in this constraint. Make all client-server interaction stateless. Server will not store anything about latest HTTP request client made. It will treat each and every request as new. No session, no history.

If client application needs to be a stateful application for the end user, where user logs in once and do other authorized operations thereafter, then each request from the client should contain all the information necessary to service the request – including authentication and authorization details.

No client context shall be stored on the server between requests. The client is responsible for managing the state of the application.

Cacheable
In today’s world, caching of data and responses is of utmost important wherever they are applicable/possible. The webpage you are reading here is also a cached version of the HTML page. Caching brings performance improvement for client side, and better scope for scalability for a server because the load has reduced.

In REST, caching shall be applied to resources when applicable and then these resources MUST declare themselves cacheable. Caching can be implemented on the server or client side.

Well-managed caching partially or completely eliminates some client-server interactions, further improving scalability and performance.

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, for example. A client cannot ordinarily tell whether it is connected directly to the end server, or to an intermediary along the way.

Code on demand (optional)
Well, this constraint is optional. Most of the time you will be sending the static representations of resources in form of XML or JSON. But when you need to, you are free to return executable code to support a part of your application e.g. clients may call your API to get a UI widget rendering code. It is permitted.

All above constraints help you build a truly RESTful API and you should follow them. Still, at times you may find yourself violating one or two constraints. Do not worry, you are still making a RESTful API – but not “truly RESTful”.
Notice that all the above constraints are most closely related to WWW (the web). Using RESTful APIs, you can do the same thing with your web services what you do to web pages.

REST - Part 1 What is REST?

REST is acronym for REpresentational State Transfer. It is architectural style for distributed hypermedia systems and was first presented by Roy Fielding in 2000 in his famous dissertation.

Guiding Principles of REST

Cient–server – By separating the user interface concerns from the data storage concerns, we improve the portability of the user interface across multiple platforms and improve scalability by simplifying the server components.

Stateless – Each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.

Cacheable – Cache constraints require that the data within a response to a request be implicitly or explicitly labeled as cacheable or non-cacheable. If a response is cacheable, then a client cache is given the right to reuse that response data for later, equivalent requests.

Uniform interface – By applying the software engineering principle of generality to the component interface, the overall system architecture is simplified and the visibility of interactions is improved. In order to obtain a uniform interface, multiple architectural constraints are needed to guide the behavior of components. REST is defined by four interface constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state.

Layered system – The layered system style allows an architecture to be composed of hierarchical layers by constraining component behavior such that each component cannot “see” beyond the immediate layer with which they are interacting.

Code on demand (optional) – REST allows client functionality to be extended by downloading and executing code in the form of applets or scripts. This simplifies clients by reducing the number of features required to be pre-implemented.

Resource

The key abstraction of information in REST is a resource. Any information that can be named can be a resource: a document or image, a temporal service, a collection of other resources, a non-virtual object (e.g. a person), and so on.The state of resource at any particular timestamp is known as resource representation.The data format of a representation is known as a media type.


Resource Methods
Other important thing associated with REST is resource methods to be used to perform the desired transition. A large number of people wrongly relate resource methods to HTTP GET/PUT/POST/DELETE methods.

Roy Fielding has never mentioned any recommendation around which method to be used in which condition. All he emphasizes is that it should be uniform interface. If you decide HTTP POST will be used for updating a resource – rather than most people recommend HTTP PUT – it’s alright and application interface will be RESTful.

Ideally, everything that is needed to change the resource state shall be part of API response for that resource – including methods and in what state they will leave the representation.


REST and HTTP are not same !!
A lot of people prefer to compare HTTP with REST. REST and HTTP are not same.

REST != HTTP

Though, because REST also intend to make web (internet) more streamline and standard, he advocate to use REST principles more strictly. And that’s from where people try to start comparing REST with web (HTTP). Roy fielding, in his dissertation, nowhere mentioned any implementation directive – including any protocol preference and HTTP. Till the time, you are honoring the 6 guiding principles of REST, you can call your interface RESTful.

In simplest words, in the REST architectural style, data and functionality are considered resources and are accessed using Uniform Resource Identifiers (URIs). The resources are acted upon by using a set of simple, well-defined operations. The clients and servers exchange representations of resources by using a standardized interface and protocol – typically HTTP.

Resources are decoupled from their representation so that their content can be accessed in a variety of formats, such as HTML, XML, plain text, PDF, JPEG, JSON, and others. Metadata about the resource is available and used, for example, to control caching, detect transmission errors, negotiate the appropriate representation format, and perform authentication or access control.And most importantly, every interaction with a resource is stateless.

All these principles help RESTful applications to be simple, lightweight, and fast.