Previous Topic

Next Topic

Book Contents

Book Index

Technology Overview

REST Overview

REST (Representational State Transfer) is an architectural style which defines six constraints for engineering scalable and efficient network-based software applications. REST was first proposed by Roy Fielding in his doctoral dissertation [1]. The idea behind the creation of REST was to develop an architectural model of how the Web should work. REST is used for:

As Roy Fielding explains, the REST style "provides a set of architectural constraints that, when applied as a whole, emphasizes scalability of component interactions, generality of interfaces, independent deployment of components, and intermediary components to reduce interaction latency, enforce security, and encapsulate legacy systems" [1]. Those constraints are:

Client-Server

The client-server model of computing is a distributed application structure that divides the workload between servers called clients. Often clients and servers communicate over a network on separate hardware, but may reside in the same system. A server host provides one or more services which share their resources with clients. A client does not share any of its resources, but requests a server's content or service function. Clients initiate the communication sessions with servers.

Separation of concerns is the principle behind the client-server constraints. Separation of the user interface from the data storage concerns improves the portability of the user interface and improves scalability by simplifying the server components, allowing the components to evolve independently.

Stateless

Communication must be stateless. Each client-server request must contain all the necessary information to understand the request, and cannot use any context stored on the server. Session state is kept entirely on the client. This constraint induces visibility, reliability, and scalability. Visibility is improved because a monitoring system does not have to look beyond a single request datum in order to determine the full nature of the request. Reliability is improved because recovering from partial failures is easier. Scalability is improved because not having to store state allows the server to quickly free resources, and further simplifies implementation because the server doesn't manage resource usage across requests. The disadvantage is that network performance may decrease because of the increase in the transmitted data that cannot be stored on the server in a shared context. Furthermore, placing the application state on the client-side reduces the server's control over the application behavior, because the application depends upon the correct implementation of semantics across various client versions.

Uniform Interface

The distinguishing feature of REST is its emphasis on the uniform interface between components. By applying the generality principle to the component interface, the system architecture is simplified and the interactions visibility is improved. Implementations are independent from the services they provide, which allows them to evolve independently. Uniform interfaces degrades efficiency, due to information being transferred in a standardized rather than an application optimal form. To obtain a uniform interface, multiple constraints are needed to guide the components behavior:

Resource-Based

One of the abstractions of information in REST is a resource. All information that can be named can be a resource: documents, images, temporal services and collections of other resources. Any concept that can be the target of a hypertext reference must conform to the definition of a resource. There are two types of resources - instance and collection. An instance resource represents a singe entity in the system while a collection resource represents the collection of all such entities available in the system [1]. REST uses a resource identifier for the resource involved in an interaction between components.

Manipulation of Resources Through Representations

Components perform actions on resources by using a representation that contains the current or intended state of the resource. This representation is transferred between components using the CRUD operations. A representation is a concatenation of sequence of bytes and representation metadata that describes those bytes. The metadata is a set of name-value pairs, where the name conforms to a standard that determines the value's structure and semantics. Response messages may include both representation and resource metadata: information about the resource that is not specific to the supplied representation. The data format of a representation is known as a media type. A representation can be included in a message and processed by the recipient according to the metadata of the message and the nature of the media type.

Self-descriptive Messages

Each message includes enough information to describe how to process the message based on the resource and representation metadata.

Hypermedia as the Engine of Application State (HATEOAS)

In the context of REST, the "application state" refers to the state that determines "where" the client is in the process of completing a task. For example, in the case of managing books, the client may be retrieving the available books, creating new books or updating existing ones - those are each different application states. The word "hypermedia" stands for embedding links in the resources which can be used to control(drive) the web application. HATEOAS is based on the definition of self-descriptive resources which contain links to relative resources, thus defining valid state transitions - the name space and the valid transitions are controlled by the server, application state is driven by the client following the links. The main goal is achieving a more intuitive and more mature interface which would (given a sensible implementation of the client) grant:

Cacheable

Cache constraints require that the data within a response to a request be implicitly or explicitly labeled as cacheable or non-cacheable. If a response is cacheable, then a client cache is given the right to reuse that response data for later, equivalent requests. The advantage of adding cache constraints is that they have the potential to partially or completely eliminate some interactions, improving efficiency, scalability, and user-perceived performance by reducing the average latency of a series of interactions. The trade-off, however, is that a cache can decrease reliability if stale data within the cache differs significantly from the data that would have been obtained had the request been sent directly to the server.

Layered System

The layered system style allows an architecture to be composed of hierarchical layers by constraining component behavior such that each component cannot "see" beyond the immediate layer with which they are interacting. By restricting knowledge of the system to a single layer, we place a bound on the overall system complexity and promote substrate independence. Layers can be used to encapsulate legacy services and to protect new services from legacy clients, simplifying components by moving infrequently used functionality to a shared intermediary. Intermediaries can also be used to improve system scalability by enabling load balancing of services across multiple networks and processors.

Code on Demand

REST allows client functionality to be extended by downloading and executing code in the form of applets or scripts. This simplifies clients by reducing the number of features required to be pre-implemented. Allowing features to be downloaded after deployment improves system extensibility. However, it also reduces visibility, and thus is only an optional constraint within REST.

REST and HTTP

REST is neither a standard, nor a protocol, REST gives a coordinated set of constraints to the design of components in a distributed hypermedia system that can lead to a higher performing and more maintainable architecture. REST was initially described in the context of HTTP (Hypertext Transfer Protocol), but is not limited to that protocol. RESTful architectures can be based on other application layer protocols if they already provide a rich and uniform vocabulary based on the transfer of meaningful representational state. RESTful applications maximize the use of the pre-existing, well-defined interface and other built-in capabilities provided by the chosen network protocol, and minimize the addition of new application-specific features on top of it. HTTP is server-client, it defines an interface with its methods (GET, POST, PUT, DELETE, PATCH, etc.) and various headers which can be used uniformly for interacting with resources. This uniformity can be achieved with other protocols as well but HTTP is most widely used and when we talk about RESTful web services we assume HTTP.

Java Standards

JAX-RS

Java API for RESTful Services (JAX-RS) specification defines a flexible and extensible Java API for development of web services built according to the REST architectural style [2]. The API is consisted of a set of annotations and associated classes/interfaces that may be used with POJOs in order to expose them as web resources. The specification assumes HTTP as the underlying network protocol for transferring resource representations and provides a clear mapping between HTTP and URI elements and the corresponding API classes and annotations. The API is representation-agnostic and applicable to a wide variety of HTTP entity body content types, thus provides the necessary pluggability to allow additional types to be added by an application in a standard manner.

A JAX-RS container provides an implementation of the JAX-RS specification, thus manages the various JAX-RS components available in the Java runtime:

JAX-RS Applications

A JAX-RS application consists of one or more resources and zero or more providers. The resources and providers that make up a JAX-RS application are configured via an application-supplied subclass of Application. An implementation may provide alternate mechanisms for locating resource classes and providers but use of Application is the only portable means of configuration.

JAX-RS Resources

Using the JAX-RS Web resource is implemented as a resource class and requests are handled by resource methods. By default a new resource class instance is created by the JAX-RS container for each request to that resource. First the constructor is called, then any requested dependencies are injected, then the appropriate method is invoked and finally the object is made available for garbage collection.

A resource class is a Java class that uses JAX-RS annotations to implement a corresponding Web resource. Resource classes are POJOs that are annotated with @Path (root resource classes) or have at least one method annotated with @Path and/or a request method designator. A request method designator is a runtime annotation that is annotated with the @HttpMethod annotation. JAX-RS defines a set of request method designators for the common HTTP methods: @GET, @POST, @PUT, @DELETE, @HEAD. Methods of a resource class that are annotated with @Path are either sub-resource methods or sub-resource locators. Sub-resource methods are annotated with a request method designator and handle a HTTP request directly whilst sub-resource locators return an object that will handle a HTTP request. Resource methods are methods of a resource class annotated with a request method designator.

JAX-RS Providers

The JAX-RS runtime may be extended using application-supplied provider classes. A provider is annotated with @Provider and implements one or more interfaces defined by JAX-RS. By default a single instance of each provider class is instantiated by the JAX-RS container for each JAX-RS application. First the constructor is called, then any requested dependencies are injected, then the appropriate provider methods may be called multiple times (simultaneously), and finally the object is made available for garbage collection.

The specification defines several types of JAX-RS providers:

Entity providers supply mapping services between representations and their associated Java types. There are two types of entity providers – MessageBodyReader and MessageBodyWriter. The MessageBodyReader interface defines the contract between the JAX-RS runtime and components that provide mapping services from representations to a corresponding Java type. A class wishing to provide such a service implements the MessageBodyReader interface and is annotated with @Provider. The MessageBodyWriter interface defines the contract between the JAX-RS runtime and components that provide mapping services from a Java type to a representation. A class wishing to provide such a service implements the MessageBodyWriter interface and is annotated with @Provider. Message body readers and writers may restrict the media types they support using the @Consumes and @Produces annotations respectively.

Context providers supply context to resource classes and other providers, a context provider class implements the ContextResolver<T> interface and is annotated with @Provider.

When a resource class or provider method throws an exception, the JAX-RS runtime will attempt to map the exception to a suitable HTTP response. An application can supply exception mapping providers to customize this mapping. Exception mapping providers map a checked or runtime exception to an instance of Response. An exception mapping provider implements the ExceptionMapper<T> interface and is annotated with @Provider. When a resource method throws an exception for which there is an exception mapping provider, the matching provider is used to obtain a Response instance. The resulting Response is processed as if the method throwing the exception had instead returned the Response.

JAX-RS Context

JAX-RS provides facilities for obtaining and processing information about the application deployment context and the context of individual requests. Such information is available to application classes, root resource classes and providers. Context is specific to a particular request but instances of certain JAX-RS components may need to support multiple concurrent requests.

The specification defines several injectable interfaces:

The instance of the application-supplied Application subclass can be injected by the JAX-RS container into a class field or method parameter using the @Context annotation. Access to the Application subclass instance allows configuration information to be centralized in that class.

The instance of the application-supplied Application subclass cannot be injected into the Application subclass itself since this would create a circular dependency.

An instance of UriInfo can be injected by the JAX-RS container into a class field or method parameter using the @Context annotation. The UriInfo interface provides both static and dynamic, per-request information, about the components of a request URI.

An instance of HttpHeaders can be injected by the JAX-RS into a class field or method parameter using the @Context annotation. The HttpHeaders interface provides access to request header information either in map form or via strongly typed convenience methods.

JAX-RS simplifies support for content negotiation and preconditions using the Request interface. An instance of Request can be injected by the JAX-RS container into a class field or method parameter using the @Context annotation.

The Providers interface allows for lookup of provider instances based on a set of search criteria. An instance of Providers can be injected by the JAX-RS container into a class field or method parameter using the @Context annotation. This interface is expected to be primarily of interest to provider authors wishing to use other providers functionality.

JAXB

Java Architecture for XML Binding (JAXB) specification defines an XML-to-Java binding architecture that simplifies the development of web services by enabling transformations between schema and Java objects and between XML instance documents and Java object instances [3]. An XML schema defines the data elements and structure of an XML document. JAXB APIs and tools can be used to establish mappings between Java classes and XML schema. JAXB technology provides the tools that enable conversion of XML documents to and from Java objects. In addition, JAXB is supported by a variety of JSON-processing tools enabling mapping and conversion of JSON documents, as well. JAXB may be used for modeling RESTful web services resources which represent custom Java types in order to simplify the mapping between JSON/XML resource representations and Java objects and avoid the necessity of custom JAX-RS entity providers for serialization and deserialization.

Most commonly used JAXB annotations:

Maps a class or an enum type to an XML element. This annotation can be used with the following program elements: a top level class, an enum type. When a top level class or an enum type is annotated with the @XmlRootElement annotation, then its value is represented as XML element in an XML document.

Maps a JavaBean property to a XML element derived from property name. This annotation can be used with the following program elements: a JavaBean property, non static, non transient field within XmlElements. A JavaBean property, when annotated with @XmlElement annotation is mapped to a local element in the XML Schema complex type to which the containing class is mapped.

Maps a class or an enum type to a XML Schema type. This annotation can be used with the following program elements: a top level class, an enum type. A class maps to either a XML Schema complex type or a XML Schema simple type. The XML Schema type is derived based on the mapping of JavaBean properties and fields contained within the class. The schema type to which the class is mapped can either be named or anonymous. A class can be mapped to an anonymous schema type by annotating the class with @XmlType(name="").

References