-
Book Overview & Buying
-
Table Of Contents
-
Feedback & Rating

RESTful Java Web Services
By :

Having learned the basics of a RESTful system, you are now ready to meet more exciting concepts around REST. In this section, you will learn the core architectural elements that make a system RESTful.
Analogous to any software architecture, the REST architecture is also defined by a configuration of key architectural elements (components, connectors, and data) with a set of constraints, as shown in the following diagram:
The central feature that distinguishes the REST architectural style from other network-based styles is its emphasis on a uniform interface between components, which abstracts the information being transmitted. A uniform interface is fundamental to the architecture of any RESTful system. In plain words, this term refers to a generic interface to manage all interactions between a client and server in a unified way. All resources (or business data) involved in the client-server interactions are dealt with a fixed set of operations. The following are the core elements that form a uniform interface for a RESTful system:
Let's look at these items in detail in the following section.
A RESTful resource is anything that is addressable over the web. By addressable, we mean resources that can be accessed and transferred between clients and servers. Subsequently, a resource is a logical, temporal mapping to a concept in the problem domain for which we are implementing a solution.
Here are some examples of REST resources:
Even though a resource's mapping is unique, different requests for a resource can return the same underlying binary representation stored in the server. For example, let's say we have a resource within the context of a publishing system. Then, a request for the latest revision published and the request for revision number 12 will at some point in time return the same representation of the resource. In this example, the last revision is version 12. However, when the latest revision published is increased to version 13, a request to the latest revision will return version 13, and a request for the revision of version 12 will continue returning version 12. This implies that in a RESTful architecture, each resource can be accessed directly and independently, and sometimes, different requests may point to the same resource.
As we are using HTTP to communicate, we can transfer a variety of data types between clients and servers, as long as the data type used is supported by HTTP. For example, if we request a text file from CNN, our browser receives a text file. If we request a Flash movie from YouTube, our browser receives a Flash movie. The data is streamed in both cases over TCP/IP and the browser knows how to interpret the binary streams because of the Content-Type
header present in the HTTP response header. Following this principle, in a RESTful system, the representation of a resource in the response body depends on the desired internet media type, which is specified within the request header sent by the client.
A URI is a string of characters used to identify a resource over the web. In simple words, the URI in a RESTful web service is a hyperlink to a resource, and it is the only means for clients and servers to exchange representations.
The client uses a URI to locate the resources over web, sends a request to the server, and reads the response. In a RESTful system, the URI is not meant to change over time as it may break the contract between the client and server. More importantly, even if the underlying infrastructure or hardware changes (for example, swapping the database servers) for a server hosting the REST APIs, the URIs for the resources are expected to remain the same as long as the web service is up and running.
The representation of resources is what is sent back and forth between clients and servers in a RESTful system. A representation is a temporal state of the actual data located in a storage device at the time of request. In general terms, it is a binary stream, together with its metadata, which describes how the stream is to be consumed by the client. The metadata can also contain extra information about the resource, for example, validation, encryption information, or extra code to be executed at runtime.
Throughout the life of a web service, there may be a variety of clients requesting resources. Different clients can consume different representations of the same resource. Therefore, a representation can take various forms, such as an image, a text file, an XML, or a JSON format. However, all clients will use the same URI with appropriate Accept
header values for accessing the same resource in different representations.
For the human-generated requests through a web browser, a representation is typically in the form of an HTML page. For automated requests from other web services, readability is not as important, and a more efficient representation, such as JSON or XML, can be used.
In the previous sections, we introduced the concepts of resources and representations. We learned that resources are mappings of the actual entity states that are exchanged between clients and servers. Further, we discussed that representations are negotiated between clients and servers through the communication protocol (HTTP) at runtime. In this section, you will learn about the generics of interaction semantics and self-descriptive messages followed for the client-server communication in a RESTful system.
Developing RESTful web services is similar to what we have been doing up to this point with our web applications. In a RESTful web service, resources are exchanged between the client and the server, which represent the business entities or data. HTTP specifies methods or actions for the resources. The most commonly used HTTP methods or actions are POST
, GET
, PUT
, and DELETE
. This clearly simplifies the REST API design and makes it more readable. On the other hand, in traditional application development, we can have countless actions with no naming or implementation standards. This may call for more development effort for both the client and the server and make the APIs less readable.
In a RESTful system, we can easily map our CRUD actions on the resources to the appropriate HTTP methods such as POST
, GET
, PUT
, and DELETE
. This is shown in the following table:
Data action | HTTP equivalent |
|
|
|
|
|
|
|
|
In fact, the preceding list of HTTP methods is incomplete. There are some more HTTP methods available, but they are less frequently used in the context of RESTful implementations. Of these less frequent methods, OPTIONS
and HEAD
are used more often than others. So, let's glance at these two method types:
OPTIONS
: This method is used by the client to determine the options or actions associated with the target resource, without causing any action on the resource or retrieval of the resource
HEAD
: This method can be used for retrieving information about the entity without having the entity itself in the responseIn their simplest form, RESTful web services are networked applications that manipulate the state of resources. In this context, resource manipulation means resource creation, retrieval, updation, and deletion. However, RESTful web services are not limited to just these four basic data manipulation concepts. They can even be used for executing business logic on the server but remembering that every result must be a resource representation of the domain at hand.
A uniform interface brings all the aforementioned abstractions into focus. Consequently, putting together all these concepts, we can describe RESTful development with one short sentence--we use URIs to connect clients and servers in order to exchange resources in the form of representations.
Let's now look at the four HTTP request types in detail and see how each of them is used to exchange representations to modify the state of resources.
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?
GET
method type and IT
as the identifier for the department.Accept
request header field. This request message is self-descriptive:GET
method in this example) with known semantics for retrieving the contentGET
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.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.
The POST
method is used to create resources. As we are creating a department, we use the HTTP POST
method. Again, the URI to create a new department in our example is http://www.packtpub.com/resources/departments
. The method type for the request is set by the client.
Assume that the Sales
department does not exist in our list, and we want to add it to the list. The Sales
data representation looks like the following:
{"departmentName":"Sales","manager":"Tony Greig"}
Now, the sequence diagram of our POST
request looks like the following:
The series of steps for the POST
request is as follows:
http://www.packtpub.com/resources/departments
URI with the HTTP method set to POST
.POST
request carries the payload along with it in the form of a JSON representation of the Sales
department.REST
framework handle it; our code within the framework executes the proper commands to store the representation, irrespective of which data persistence mechanism is used.2xx
(representing successful operation), is sent back. In this example, the server sends 201 Created
, which implies that the server has fulfilled the request by creating a new resource. The newly created resource is accessible by traversing the URI given by a Location
header field. If it fails, then the server sends the appropriate error code.
The PUT
method is used to update resources. To update a resource, we first need its representation in the client. Then, at the client level, we update the resource with the new value(s) that we want. Finally, we update the resource by using a PUT
request together with the representation as its payload.
In this example, let's add a manager to the Sales
department, which we created in the previous example.
Our original representation of the Sales
department is as follows:
{"departmentId":40,"departmentName":"Sales","manager":"Tony Greig" }
Let's update the manager for the Sales
department; our representation is as follows:
{"departmentId":40,"departmentName":"Sales","manager":"Ki Gee"}
We are now ready to connect to our web service to update the Sales
department by sending the PUT
request to http://www.packtpub.com/resources/departments/Sales
. The sequence diagram of our PUT
request is as follows:
The series of steps for the PUT
request is as follows:
PUT
request to http://www.packtpub.com/resources/departments/Sales
with the JSON payload representing the modified department details.Sales
department. Once completed, a response is sent back. The 204 No Content
response code indicates that the server has fulfilled the request but does not return the entity body.The DELETE
method is used to delete the resource. In this example, we will delete a resource by making use of the same URI that we used in the other three cases.
Assume that we want to delete the Sales
department from the data storage. We send a DELETE
request to our service with the following URI: http://www.packtpub.com/resources/departments/Sales
The sequence diagram for our DELETE
request is shown in the following diagram:
The series of steps for the DELETE
request is as follows:
DELETE
request to http://www.packtpub.com/resources/departments/Sales
.Sales
department.With this, we have covered all the major actions that can be carried out on resources in a RESTful web service. To keep things simple during our discussion, we did not talk about the actual implementation of the CREATE
, READ
, UPDATE
, and DELETE
operations on the resource. In all three examples, we presumed that we have a well-behaved web service that adheres to the RESTful guidelines, and the client and server communicate over HTTP. We use the communication protocol to send action requests, and our resource representations are sent back and forth through unchanging URIs. We will cover more detailed end-to-end examples later in this book.
A point to note about our sequence diagrams is that we are assuming that all the underlying technologies are Java technologies (servers and clients). However, these are just components in the whole architecture and the explanations apply to any technology stack.
Hypermedia as the Engine of Application State (HATEOAS) is an important principle of the REST application architecture. The principle is that the model of application changes from one state to another by traversing the hyperlinks present in the current set of resource representations (model). Let's learn this principle in detail.
In a RESTful system, there is no fixed interface between the client and the server, as you may see in a conventional client-server communication model such as Common Object Request Broker Architecture (CORBA) and Java Remote Method Invocation (Java RMI). With REST, the client just needs to know how to deal with the hypermedia links present in the response body; next, the call to retrieve the appropriate resource representation is made by using these dynamic media links. This concept makes the client-server interaction very dynamic and keeps it different from the other network application architectures.
Here is an example illustrating the HATEOAS principle. In this example, the http://www.packtpub.com/resources/departments/IT
URI returns the following response to the client:
{"departmentId":10, "departmentName":"IT", "manager":"John Chen, "links": [ { "rel": "employees", "href": "http://packtpub.com/resources/departments/IT/employees" } ]"}
This is the current state of the system. Now, to get the employees belonging to the department, the client traverses the hyperlink present in the response body, namely http://www.packtpub.com/resources/departments/IT/employees
. This URI returns the following employee list. The application state now changes into the following form (as represented by the response content):
[{"employeeId":100, "firstName":"Steven", "lastName":"King", "links": [ { "rel": "self", "href": "http://www.packtpub.com/resources/employees/100" }] }, {"employeeId":101, "firstName":"Neena", "lastName":"Kochhar", "links": [ { "rel": "self", "href": "http://www.packtpub.com/resources/employees/101" }] }]
In this example, the application state changes from one state to another when the client traverses the hypermedia link. Hence, we refer to this implementation principle as HATEOAS.
Connectors provide decoupling between components by encapsulating the underlying implementation of resources and communication mechanisms using various connector types, as described in the following table:
Connector type | Function | Examples |
Client | Initiates the request and accepts the response | Client-side web APIs ( |
Server | Listens for connections and responds to requests | Web server APIs (Apache API, NSAPI) |
Cache | Used for storing cacheable responses both at the client and server side to optimize interaction latency | Web caching solutions (Akamai, Cloudflare, Microsoft Azure CDN) |
Resolver | Resolves web address to the corresponding network address | BIND, Microsoft DNS, AnswerX |
Tunnel | Relays communication across a connection boundary such as firewall, gateways, or proxies. | SOCKS, HTTP Tunnel |
Software components required for REST are categorized by their roles as follows:
Component role | Function | Examples |
Origin server | It acts as the container or definitive source for the representation of resources being requested; it must be the ultimate recipient of any requests. It uses a server connector to receive and respond to requests. | Web servers (Apache Tomcat, Microsoft IIS) |
User agent | This is the user interface for the end user. It uses the client connector to initiate the request and get the response. | Web browsers (Internet Explorer, Chrome, Lynx) |
Proxy | This acts as an intermediary for requests from clients seeking resources. | CGI Proxy, CERN Proxy |
Gateway | This involves reverse proxies providing encapsulation of services such as security (encryption), performance enhancement (load balancing), or data translation (compression). | Squid, NGINX |
Change the font size
Change margin width
Change background colour