The GET method is used to retrieve resources. Before digging into the actual mechanics of the HTTP GET request, we first need to determine what a resource is in the context of our web service and what type of representation we are exchanging.
For the rest of this section, we will use the example of a RESTful web service handling the department details for an organization. For this service, the JSON representation of a department looks as follows:
{"departmentId":10,"departmentName":"IT","manager":"John Chen"}
The JSON representation of the list of departments looks as follows:
[{"departmentId":10,"departmentName":"IT","manager":"John Chen"},
{"departmentId":20,"departmentName":"Marketing","manager":"Ameya
J"},
{"departmentId":30,"departmentName":"HR","manager":"Pat Fay"}]
With our representations defined, we can now assume URIs of the form http://www.packtpub.com/resources/departments to access a list of departments, and http://www.packtpub.com/resources/departments/{name} to access a specific department with a name (unique identifier).
To keep this example simple and easy to follow, we treat the department name as a unique identifier here. Note that in real life, you can use a server-generated identifier value, which does not repeat across entities, to uniquely identify a resource instance.
We can now begin making requests to our web service. For instance, if we wanted a record for the IT department, we make a request to the following URI: http://www.packtpub.com/resources/departments/IT.
A representation of the IT department at the time of the request may look like the following code snippet:
{"departmentId":10,"departmentName":"IT","manager":"John Chen"}
Let's have a look at the request details. A request to retrieve the details of the IT department uses the GET method with the following URI: http://www.packtpub.com/resources/departments/IT
Let's see what happens when a client requests for the IT department with the aforementioned URI. Here is the sequence diagram for the GET request:
What is happening here?
- A Java client makes an HTTP request with the GET method type and IT as the identifier for the department.
- The client sets the representation type that it can handle through the Accept request header field. This request message is self-descriptive:
-
- It uses a standard method (the GET method in this example) with known semantics for retrieving the content
- The content type is a set to a well-known media type (text/plain)
- This request also declares the acceptable response format
- The web server receives and interprets the GET request to be a retrieve action. At this point, the web server passes control to the underlying RESTful framework to handle the request. Note that RESTful frameworks do not automatically retrieve resources, as that is not their job. The job of a framework is to ease the implementation of the REST constraints. Business logic and storage implementation is the role of the domain-specific Java code.
- The server-side program looks for the IT resource. Finding the resource could mean looking for it in some data store such as a database, a filesystem, or even a call to a different web service.
- Once the program finds the IT department details, it converts the binary data of the resource to the client's requested representation. In this example, we use the JSON representation for the resource.
- With the representation converted to JSON, the server sends back an HTTP response with a numeric code of 200 together with the JSON representation as the payload. Note that if there are any errors, the HTTP server reports back the proper numeric code, but it is up to the client to correctly deal with the failure. Similar to the request message, the response is also self-descriptive.
All the messages between a client and server are standard HTTP calls. For every retrieve action, we send a GET request, and we get an HTTP response back, with the payload of the response being the representation of the resource or, if there is a failure, a corresponding HTTP error code (for example, 404 if a resource is not found or 500 if there is a problem with the Java code in the form of an exception).
Getting a representation for all the departments works in the same way as getting the representation for a single department, although we now use the URI as http://www.packtpub.com/resources/departments and the result is the JSON representation, which looks as follows:
[{"departmentId":10,"departmentName":"IT","manager":"John Chen"},
{"departmentId":20,"departmentName":"Marketing","manager":"Ameya
J"},
{"departmentId":30,"departmentName":"HR","manager":"Pat Fay"}]
The HTTP
GET method should only be used to retrieve representations, not for performing any update on the resource. A
GET request must be safe and idempotent. For more information, refer to
http://www.w3.org/DesignIssues/Axioms.
For a request to be safe, it means that multiple requests to the same resource do not change the state of the data in the server. Assume that we have a representation, R, and requests happen at time t. Then, a request at time t1 for the resource R returns R1; subsequently, a request at time t2 for the resource R returns R2, provided that no further update actions have been taken between t1 and t2. Then, R1 = R2 = R.
For a request to be idempotent, multiple calls to the same action should not change the state of the resource. For example, multiple calls to create the resource R at times t1, t2, and t3 means that R will exist only as R and the calls at times t2 and t3 are ignored.