Chapter 2

2.1. HTTP Request

Here is what a request message looks like:

GET /v2/blog/good.tumblr.com/info HTTP/1.1
Host: api.tumblr.com
Cache-Control: no-cache

The first line, called the request line, contains three parts - the request method (GET), the resource identifier (/v2/blog/good.tumblr.com/info) and protocol version (HTTP/1.1).

Request Methods

Request methods indicate how the resource should be requested. The most common methods are GET and POST.

In the Tumblr example in Chapter 1, we used GET to retrieve the blog’s information from https://api.tumblr.com/v2/blog/good.tumblr.com/info. The GET method requests a representation of the specified resource. Simply put, it retrieves data. The POST method on the other hand is used to send data to the resource for processing.

It is important to note that even though GET is used to request data, GET requests can send data to the resource as well. However, the way the data is transmitted differs from POST in a couple of ways:

  1. GET passes the data through the URL. POST passes the data through the message body. (I will explain better shortly).
  2. Because URLs are limited in length, there is a limit to the size of data you can send through GET. You can send a lot of data, even files, with POST.

You will see many REST APIs use only GET and POST. But these are not the only HTTP request methods that exist. Others include HEAD, PUT, DELETE, TRACE, OPTIONS, CONNECT and PATCH. We will however limit our scope to GET, POST, HEAD, PUT and DELETE.

The HEAD method is similar to GET. The difference is it only returns the status information about the request without the response body. So while a GET request may return a response like, “The file you requested is available. It is 35kB in size. Here is the content…”, a HEAD request will return a response like, “Yes I have the file you requested. It is 35kB in size. (Ask for the content if you need it)”. The HEAD method is really handy when you are only concerned about metadata information like size or type and not the content itself.

PUT requests that the represented resource be updated with the sent data.

DELETE, as the name implies, requests representations of the resource be removed. As an example, I can delete a comment (of an authenticated user) on Instagram by sending the following DELETE request

DELETE /v1/media/{media-id}/comments/{comment-id}?
	access_token={access_token} HTTP/1.1
Host: api.instagram.com

Request Headers

GET /v2/blog/good.tumblr.com/info HTTP/1.1
Host: api.tumblr.com
Cache-Control: no-cache

The second and third lines in our example are called headers. Headers are used to pass additional information about the request or the client to the server. They have the format:

Name: Value

For this request, the headers are HOST and Cache-Control.

The Host header is used to specify the domain name of the server we are sending the request to.

Cache-Control1 is used to specify the caching rule for the request-response. One of REST’s principles is that responses should be labeled as cacheable or non-cacheable. The Cache-Control header helps the client determine if the result can be cached or not.

There are many other headers that are standard for requests. Most of them are self explanatory. Some of these headers also apply to responses. You will see more as we proceed. Here are the common ones:

  • Content-Type: The content format of the request body
  • Content-Length: The length of the request body in 8-bit bytes
  • Date: Message date and time
  • Accept: Content-Types that are acceptable for the request
  • Connection: Options for this connection

A full list of HTTP headers is available here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Message Body

The message body is used to send request data to the server. But our example request does not include a message body. This is because it is a GET request and GET requests do not send data through the message body. To see what the request message body looks like, let’s consider a POST request to the Tumblr API. We simply follow the HTTP message format I mentioned earlier:

An initial line Zero or more header lines A blank line, and An optional message body (the POST data)

POST /v2/blog/good.tumblr.com/post HTTP/1.1
Host: api.tumblr.com
Content-Length: [post data length]
Content-Type: [Post data type]

[Post data]

Our POST data can be anything and of any type. What is important is we let the server know what type of content we are sending. Hence the need for the Content-Type header. We also add a Content-Length header so the server knows the length of the data.

The most common way data is sent through POST is as name-value pairs.

title: Hello World
body: This is a test post :)
tags: test
type: text

No, not directly like that. The data is first formatted in a special way.

  1. The name-value pairs are separated with ‘&’



    title: Hello World&body: This is a test post :)&tags: test&type: text


  2. The names and values are then separated with ‘=’



    title=Hello World&body=This is a test post :)&tags=test&type=text


  3. Spaces are replaced with ‘+’



    title=Hello+World&body=This+is+a+test+post+:)&tags=test&type=text


  4. Other non-alphanumeric characters in the value are replaced with a percent sign and two hexadecimal digits representing the ASCII code of the character (the colon “:” becomes %3A and “)” becomes %29)



    title=Hello+World&body=This+is+a+test+post+%3A%29&tags=test&type=text

This is called URL encoding or Percent encoding2. I know you are a bit confused about step 4 but not to worry, there are inbuilt functions to perform this encoding in modern programming languages.

This content type is called application/x-www-form-urlencoded. It is the default content type for sending POST data.

Now we can have our complete POST request:

POST /v2/blog/good.tumblr.com/post HTTP/1.1
Host: api.tumblr.com
Content-Length: 69
Content-Type: application/x-www-form-urlencoded

title=Hello+World&body=This+is+a+test+post+%3A%29&tags=test&type=text

Sending data through a GET request is similar. But we do not need the message body, and consequently, the Content-Length and Content-Type headers. The data is passed through the URL. The URL is joined to the URL encoded string with a ‘?’ character.

GET /v2/blog/good.tumblr.com/posts/queue?filter=html&limit=100 HTTP/1.1
Host: api.tumblr.com

The part of the URL containing the data, i.e. the one after the question mark (filter=html&limit=100 in the example above), is called the query string.

  1. To understand cache-control headers better, see ‘A Beginner’s Guide to HTTP Cache Headers’: http://www.mobify.com/blog/beginners-guide-to-http-cache-headers/

  2. Percent-encoding: https://en.wikipedia.org/wiki/Percent-encoding