[This article was written by David Tracey.]
In spite of its title, this blog is not about how to enter a relaxed or restful state, but instead, presents some of the concepts behind REST (REpresentational State Transfer) and links to more information. It will show that simply returning JSON over HTTP is not a REST API. At Logentires, we are using the RESTful style to extend the flexibility of our architecture which will allow us to make features available to users through REST APIs in the future.
Why use REST?
Like any good API, a REST API is based on meeting the requirements of the client systems and their users. It defines a service, that allow clients to easily connect, address, and consume resources in accordance with the core REST principles and constraints.
This gives the following benefits:
- Generality of interfaces
- Independent deployment and evolution of components
- Encapsulation of legacy systems
How can we say these are benefits of REST?…because the Web is an example how to use the RESTful Architectural style to build a massively scalable distributed system.
What is REST?
REST was introduced in 2000 by Roy Fielding, in the dissertation, “Architectural Styles and the Design of Network-based Software Architectures” and outlined in http://www.ics.uci.edu/~fielding/pubs/webarch_icse2000.pdf. Fielding proposed a set of principles or constraints for a software style that restricts the roles/features of architectural elements, and their allowed relationships. He states that “the central feature that distinguishes the REST architectural style from other network based styles, is its emphasis on a uniform interface between components”.
REST is based on a client server model. The server is where resources are made available, (perhaps from underlying data storage) and the client makes requests to servers using a defined and limited set of operations on those resources.
The resource is returned using a representation, based on what the server supports and the client wants/supports, where:
- A representation is a machine-readable sequence of bytes (and metadata to describe those bytes) for a resource, e.g. HTML, XML, JSON or a custom MIME
- A resource is the abstraction for information made available. The contents of the resource are sets of entities/values. Each resource will have its own resource identifier (or URI) and is generally named as a noun, e.g. a user.
According to Fielding, a REST API must not define fixed-resource names/hierarchies, and must be “hypertext driven”. Meaning, application state changes are driven by client selection of server-provided choices, so a service should:
- have an entry point Uniform Resource Identifier (URI). See “Cool URIs don’t change” at http://www.w3.org/Provider/Style/URI.html
- know and use the supported media types
- allow clients to discover resources available and their URIs
- allow clients to access those resources via URIs
The RESTful system constraints
Fielding defined the following set of architectural constraints for a RESTful system. They deliberately LIMIT how to build a distributed system to maximize its scalability and independence of components:
- Client/server: Processing is divided between them, with the client focus on UI and the server on data storage allowing separate evolution.
- Stateless: The client is responsible for session-state, and each client request must contain all the information for the server to respond. The server is stateless, meaning it doesn’t have to know what state the client is in.
- Caching: The service indicates which requests may be cached.
- Uniform Interface: The service enables clients to view and interact with representations of resources (with a URI) using a generic, finite set of requests, e.g the HTTP verbs. It uses Hypermedia As The Engine Of Application State (HATEOAS), e.g. a hyperlink that specifies which page a browser can load next. This is one reason a web browser doesn’t (usually) break if a website is redesigned, as it is (usually) made up of self-descriptive HTML pages.
- Layered System: The service may be built on many layers of other systems, but these are not visible to the client, and each layer only has to know about the immediate component/layer it interacts with.
These constraints mean that clients can be based on well defined behavior, e.g. the understood and safe nature of HTTP GET compared to the behavior of specific getSomeEntity() methods found in non RESTful APIs.
Rest and HTTP
REST is an architectural style, and while it can be implemented over other communication protocols, it is often implemented using HTTP. Experience has shown that despite the limited set of HTTP verbs, (GET/PUT/POST/DELETE) it does provide a uniform interface that can handle a range of user operations.
I have several specific guidelines for a REST API over HTTP, but among the most important:
- Have an entry URI (as above)
- Don’t use HTTP cookies (it breaks the desired stateless interaction)
- API should use ONLY the standard HTTP verbs.
For example, using GET is a safe operation, and if repeated multiple times, will always return the latest copy of a particular resource. So, making a GET request to a URL, like http://www.somewhere.com/account/add to create an “account” is not RESTful. This use of GET breaks the expected behavior and would be non-obvious to developers. Either PUT or POST should be used to create a resource, depending on whether the server or client supplies the resource id.
Final thoughts and links
In summary, this blog has shown the key concepts behind REST, its benefits and that there is more to REST than just providing JSON over HTTP.
If you want to read more:
A useful summary and links can be found at the wiki site: http://en.wikipedia.org/wiki/Representational State Transfer
A good list of frameworks is at: http://code.google.com/p/implementing-rest/wiki/RESTFrameworks
Roy Fielding’s views on the importance of hypertext are at: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-drivenIf you want to experiment with building REST services, Dropwizard (dropwizard.github.io) provides a library that includes Jersey (the reference implementation of the Java Restful Web Service JAX-RS). Restlet ( www.restlet.com ) is another easy-to-use platform to develop REST services.