Wednesday, September 23, 2015

Content Negotiation : CONTENT-TYPE & ACCEPT HEADERS

When one client machine talks to another machine (lets say one computer talks to another) to get some information, it sends a HTTP request (There are many ways to talk, but we will limit our conversation to HTTP only), The HTTP request contains a lot of interesting data which can be manipulated by the server to build the response for them. HTTP request contains Headers & content. Headers are the meta data about the request. They can reveal every information, like what type of information is being sent, i.e. image/ text/ json/ xml etc. They can also mention what format of response they are expecting. Server process these headers to understand request & generate response type. This is called Content Negotiation. 

There are two very important headers which can be sent along the request to define these properties.

- CONTENT-TYPE (Define the data type of request)
- ACCEPT (Define the expected response format)


To explain this, Let's send some request to a local test server. First sending the request without any content-type set.

Request (No meta data)
POST http://localhost:3050/api/v2/tasks HTTP/1.1
User-Agent: Fiddler
Host: localhost:3050
Content-Length: 43
{"Subject":"This is the most interesting "}
Response
HTTP/1.1 415 Unsupported Media Type
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcVEZTXExlYXJuaW5nXFdlYkFQSVxzcmNcV2ViQXBpMkJvb2suV2ViLkFwaVxhcGlcdjJcdGFza3M=?=
X-Powered-By: ASP.NET
Date: Wed, 23 Sep 2015 09:38:09 GMT
Content-Length: 794
 
You see that server returned 415 error, means it could not understand the request data type so as a return could not choose any media for-matter to serialize the data, even if we are passing the JSON. Now, let's exclusively define that we are sending JSON.

Request (JSON)

We are defining exclusively that we are sending JSON this time by defining the content-type header. There is a space between the code to define content of the request.

POST /api/v2/tasks HTTP/1.1
User-Agent: Fiddler
Host: localhost:3050
Content-Length: 43
Content-Type: application/json
{"Subject":"This is the most interesting "}


Response (JSON)

And yes, Server very easily understood the input type, choose a media formatter to process the request and send the response in default return type. The default return type in my application is JSON. The way request use to define its data type, response does the same, You can see a Content-Type in response as well, it means the response contains the JSON format. This will help client to understand the data type.

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcVEZTXExlYXJuaW5nXFdlYkFQSVxzcmNcV2ViQXBpMkJvb2suV2ViLkFwaVxhcGlcdjJcdGFza3M=?=
X-Powered-By: ASP.NET
Date: Wed, 23 Sep 2015 09:45:31 GMT
Content-Length: 174
{"TaskId":0,"Subject":"In V2, Task Subject ","StartDate":null,"DueDate":null,"CreateDate":null,"CreatedBy":null,"CompleteDate":null,"Status":null,"Assignees":null,"Links":[]}


Request (JSON) expecting XML

Now Say, i want to send the JSON, but I want to see my results in XML, So now while I am sending the request to the server, I will also send the instructions to build the response according to my choice. I will define ACCEPT headers, means I will only accept predefined data type as return. It's server's job to build the result in this format. Client does not need to do anything here.

POST /api/v2/tasks HTTP/1.1
User-Agent: Fiddler
Host: localhost:3050
Content-Length: 43
Content-Type: application/json
Accept:application/xml

{"Subject":"This is the most interesting "}


Response (XML)

Now server honors the request and build the response in desired format & set its meta data. See below the content-type is XML means the data returned in XML. You can find the XML text in the content of the response.

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/xml; charset=utf-8Expires: -1
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcVEZTXExlYXJuaW5nXFdlYkFQSVxzcmNcV2ViQXBpMkJvb2suV2ViLkFwaVxhcGlcdjJcdGFza3M=?=
X-Powered-By: ASP.NET
Date: Wed, 23 Sep 2015 09:47:28 GMT
Content-Length: 387
In V2, Task Subject 0