I am currently reading the book “RESTful Web Service”, before this I have very limited knowledge about REST to the point that I even don’t know what do those four characters stand for. This article is a brief reading note from Chapter 1 to 4.
REST(Representational State Transfer) is a software architectural style that defines a set of constraints to be used for creating Web services.
REST is not an architecture, it’s a set of design criteria.
Method Information & Scoping Information
A client uses the method information to convey its intention to the server. One way to convey method information in a web service is to put it in the HTTP method, such as `GET`, `HEAD`, `PUT`, `DELETE` and `POST`. Some web services prefer to look for application specific method names elsewhere in the HTTP request: usually in the URI path or the request document.
A client tells the server which part of the data set to operate on by providing the scoping information. Many web services put scoping information in the path, the alternative is to put the scoping information into the entity body.
An RPC-style web service accepts an envelope full of data from its client and sends a similar envelope back. The method and the scoping information are kept inside the envelope or on stickers applied to the envelope. A service that uses HTTP POST heavily or exclusively is probably an RPC-style service.
RESTful, Resource-Oriented Architecture
In RESTful architectures, the method information goes into the HTTP method. In Resource-Oriented Architectures, the scoping information goes into the URI.
Let’s first talk about the definitions of a resource and a URI.
- Resources: anything that’s important enough to be referenced as a thing in itself and can be stored on a computer as a stream of bits.
- URIs: the name and address of a resource which usually is descriptive and has a structure.
By definition, no two resources can be the same. However, at some moment in time, two different resources may point to the same data. For example, if the current software release is 1.0.3, then http://www.example.com/ software/releases/1.0.3.tar.gz and http://www.example.com/software/releases/latest.tar.gz refer to the same file for a while, but they are two resources because the first always point to a specific version while the second point to whatever version is the latest at the time the client access it. Moreover, a resource can have one URI or many.
A resource is a source of representations, and a representation is just any useful information about the current state of a resource.
If a server provides multiple representations of a resource, you can either
- give a distinct URI to each representation of a resource
- content negotiation: expose a Platonic form URI for the resource irrespective of representation and let the client signal what kind of representations it is willing to accept. For example, `Accept-Language` header. A client can also set the `Accept` header to specify which file format it prefers for representations.
The server is allowed to use any of this request metadata when deciding which representation to send. It’s RESTful to keep this information in the HTTP headers, and it’s RESTful to put it in the URI. The recommendation is to keep as much of this information as possible in the URI and as little as possible in request metadata. URIs get passed around but the request metadata almost always gets lost in transition.
Four Features of the ROA
- Addressability: an application is addressable if it exposes a URI for every piece of information it might conceivably serve.
- Statelessness: every HTTP request happens in complete isolation, the server never relies on information from previous requests. If that information was important, the client would have sent it again in this request. Application state ought to live on the client and resource state ought to live on the server and it is the same for every client.
- Connectedness: a web service is connected to the extent that you can put the service in different states just by following links and filling out forms.
- A Uniform Interface
HTTP provides four basic methods for the four most common operations and two less common ones (*)
- Retrieve a representation of a resource: `HTTP GET`
- Create a new resource: `HTTP PUT` to a new URI, or `HTTP POST` to an existing URI
- Modify an existing resource: `HTTP PUT` to an existing URI
- Delete an existing resource: `HTTP DELET`
- * Retrieve a metadata-only representation: `HTTP HEAD`
- * Check which HTTP methods a particular resource supports: `HTTP OPTIONS`
In a RESTful design, `POST` is commonly used to create subordinate resources: resources that exist in relation to some other “parent” resource. The difference between `PUT` and `POST` is: the client uses `PUT` when it’s in charge of deciding which URI the new resource should have. The client uses `POST` when the server is in charge of deciding which URI the new resource should have. The `POST` method is a way of creating a new resource without the client having to know its exact URI. In most cases, the client only needs to know the URI of a “parent” or “factory” resource. The server takes the representation from the entity body and uses it to create a new resource “underneath” the “parent” resource. Sometimes, when you `POST` data to a resource, it appends the information you `POST`ed to its own state, instead of putting it in a new resource.
Note: the Overloaded POST
Providing a block of data, such as the result of submitting a form, to a data-handling process. Every HTTP request has to contain method information, and when you use overloaded `POST` it can’t go into the HTTP method. The `POST` method is just a directive to the server, saying: ”Look inside the HTTP request for the real method information”, the real information may be in the URI, the HTTP headers or the entity body. An element of the RPC style has crept into the service.
When correctly used, `GET` and `HEAD` requests are safe. `GET`, `HEAD`, `PUT` and `DELETE` requests are idempotent. POST is neither safe nor idempotent.
By analogy, an operation on a resource is idempotent if making one request is the same as making a series of identical requests.
Safety and idempotence let a client make reliable HTTP requests over an unreliable network.