1.11 REST Response

We've looked at requests so far, and understood resource URIs and HTTP methods. Let's switch to responses now.

Notes

We've looked at requests so far, and understood resource URIs and HTTP methods. Let's switch to responses now.

From requests to responses

We've learned where to make requests (resource URIs) and how to make requests (HTTP methods). Time to look at responses now. When a request comes in, what should the REST web service respond with? Knowing what the client will get back from the server is an important part of the API, because the client needs to write code to handle the response.

If it were a web application, we know the response is usually an HTML page. With styling, formatting and also, of course, the actual data in a presentable format. But when it comes to RESTful web services, you don't need to do all the styling and formatting anymore. You just need to send the actual data. How do you send it?

We discussed about various standard formats that responses can be sent in, like XML and JSON. JSON has been growing in popularity, because it is much more compact and less verbose when compared to XML, especially when large data is involved. Also, more often than not, a client to a RESTful API is client side Javascript code, and sending back data in JSON means it can easily convert it to a Javascript object. Considering these advantages, we'll choose JSON as response for our social media application in this course. However, note that you do not typically need to settle for just one format. You can write APIs to support multiple response formats, and we will implement one such API endpoint later in this course to illustrate that.

Formats

Let's say our Message entity class has these four member variables: the id, the text of the message, when it was created and who created it.

public class MessageEntity {
    private long id;
    private String message;
    private Date created;
    private String author;
...
}

When a GET request is made for a specific message, say message ID 10, the JSON that you would return would look something like this:

{
    "id":"10",
    "message":"Hello world",
    "created":"2014-06-01T18:06:36.902",
    "author":"koushik"
}

But the response doesn't have to be JSON. You could return XML as well, if the client asks for it in XML format. We haven't yet covered how a client can ask for a specific format. We'll be looking at that later. But yes, a client can say "I need a JSON response" or "Give me an XML response". Here is a possible XML response for the same message ID 10.

<messageEntity>
    <id>10</id>
    <message>Hello world</message>
    <created>2014-06-01T18:06:36.902</created>
    <author>koushik</author>
</messageEntity>

Clearly the JSON response and the XML response are different. But they represent the same resource: message ID 10. So, in other words both these responses are different representations of the same resource. This is a very important thing to remember. When you make REST API calls you are sending or receiving representations of the resource. Different representations could have different formats, even though the underlying resource is the same. This is actually how REST gets its name. Representational State Transfer. You are transferring the representational state.

When you make REST API calls you are sending or receiving representations of the resource.

Message Headers

Ok, so it's great that a REST web service can return data in XML or JSON. But that brings up a problem. How does the client know what format the response is in? The client can of course request data in a particular format, but there's no guarantee that the service responds in that format. Say, a client request asks for XML. But if the REST service knows only JSON, it does return JSON ignoring the client's preference for XML. How does the client know the format then?

The answer is using HTTP headers. The HTTP protocol has a concept of request and response headers. Every HTTP request or response has a body, which is the message itself, and certain header values that contain metadata about the message. The header data could be stuff like the content length and date. One such possible header is Content-Type. The response could contain the Content-Type header with the value for JSON or XML. There are special values for JSON and XML, and we'll learn more about that when we implement this, but for now, know that the type of content is being sent back as a response header. The client can then examine this header value and then parse the response body content accordingly.

Status codes

Think about error messages in a web application. Whens something goes wrong, the application typically returns a page with an error message, maybe in bold red text. Even if it isn't in red, the message itself would give the user an idea that it's an error. But in the case of REST APIs, since the consumer is not a human, we need to provide some set of codes to the consumer to help them identify error scenarios.

HTTP specification requires the very first line of any response to be a status line. This line will have a numerical code and a short phrase explaining what the code means. This is not just for errors. Every HTTP response needs to have this line. If the response is successful, the very first line of the response will be: 200 OK

Let's take the familiar 404 error code. If a request is made on a URI, for example /messages/101 and there is no message available with ID 101, the first line of the response should be: 404 Not Found

Again, the code 404 is for the client code to read and act. The phrase Not Found is an aid to the programmer, in case they forget what the code means. Not that any programmer would ever forget what 404 means. I mean, come on!

There are a bunch of codes that are important for us to remember and use when developing a REST API. The error codes start from 100 and go up to 599. Not all of them are valid error codes though, so you don't have 500 different possible error codes. There are 5 classes of status codes and the first digit indicates what class the code belongs to: 1 to 5.

1XX Codes - Informational

The codes starting with 1XX are informational, like acknowledgement responses. We'll not be using this set of codes in this course.

2XX Codes - Success

The codes starting with 2XX are success codes. This indicates that the server received the request from the client and processed it successfully. Some examples:

200 OK

Indicates successful response. You'd return this for any request that you can successfully respond to.

201 Created

Indicates successful resource creation. Say you get a POST request for a collection URI like /messages and you successfully create a new message. You could return 200 OK to indicate success, but a better response code would be 201 Created.

204 No Content

Sometimes the server receives requests that need it to do something, but it doesn't need to return any content back. Like DELETE requests, for example. In this case, you could either return 200 OK with no response content. Or return 204 No Content, which makes it obvious that the server really intends to send nothing back.

3XX Codes - Redirection

The server sends these codes to ask the client to do further action to complete the request. For example, it could be a redirect, asking the client to send the request somewhere else.

302 Found and 307 Temporary Redirect

One of these two error codes are returned by the server if it wants the client to request elsewhere. It's a redirect.

304 Not Modified

When a client tries to get a resource that it has already got before, the server can send this status code to say "I've already given you this resource a little while back, and nothing has changed since then."

4XX Codes - Client error

These error codes are returned if the client makes an error in the request. The request syntax could have been incorrect, or the client is requesting something that it's not supposed to see.

400 Bad Request

This is a client error. The server is not able to understand the request

401 Unauthorized

The request needs the client to sign in or authorize themselves.

403 Forbidden

The client may have authorized, but they are still not allowed to make the request. (Maybe they don't have the right access rights).

404 Not Found

No description required. :)

415 Unsupported Media Type

The client is speaking in a language that the server cannot understand

5XX Codes - Server error

The 4XX codes are when the client screws up when sending the request. The 5XX codes are when the server screws up when sending the response. It's basically the server saying, Ok, I got your request, and it looked like a valid one, but something went wrong when I tried to process it.

500 Internal Server Error

This is a generic error code. The server gets a request. The resource exists (or you'd send a 404 instead) but something went wrong when processing the request. In such cases, the standard practice is to send the error code 500, along with error details in the body of the request.

There are a bunch of other codes, but these are the important ones to remember. We'll look at more when we start implementing some of these APIs. But let me remind you again. These error codes are for you, as a web service developer to use. The clients know what it means when they see one of these error codes. So, it's up to you to send the right error codes when these events happen. For example, let's say you get a runtime exception when processing a request. You need to send back error code 500. Because it means server error. And the client will then know what's happened.

Scenarios

Let's look at the same CRUD use cases we saw in the previous tutorial, and identify what the status codes should be for the message resource

Operation URI Method Success / Failure Status code
Get message /messages/{messageId} GET Success 200
Not found 404
Failure 500
Delete message /messages/{messageId} DELETE Success 200 or 204
Not found 404
Failure 500
Edit message /messages/{messageId} PUT Success 200
Wrong format / data 400 or 415
Not found 404
Failure 500
Create message /messages POST Success 201
Wrong format / data 400 or 415
Failure 500

Hope this gives you a better idea of the status codes to be returned. Responses for other resources would mostly follow the same pattern. Again, this is just a small subset of the HTTP status codes, and we'll look at more when we start implementing APIs.

In this tutorial, we learnt about:

  1. Resource representations
  2. Message headers in HTTP and
  3. HTTP status codes