REST (REpresentational State Transfer) is and architectural style for providing standards between computer systems on the web, making it easier for systems to communicate with each other. RES-compliant systems (a.k.a RESTful systems), are characterized by how they are stateless and separate the concerns of client and server.
Separation of Client and Server
In the REST architectural style, the implementation of the client and the implementation of the server can be done independently without each other knowing about the other.
This means that the code on the client side can be changed at any time without affecting the operation of the server, and the code on the server side can be changed without affecting the operation of the client.
As long as each side knows what format of messages to send to the other, they
can be kept modular and separate. Separating the user interface concerns from
the data storage concerns, we improve the flexibility of the interface across
components.
Additionally, the separation allows each component the ability to evolve
independently.
By using a REST interface, different clients hit the same REST endpoints, perform the same actions, and receive the same responses.
Statelessness
In a RESTful system the server does not need to know anything about what state the client is in and vice versa.
In this way, both the serve and the client can understand any message received, event without seeing previous messages.
This constrain of statelessness is enforced through the use of resources, rather than commands.
Resources are the nouns of the Web - they describe any object, document, or thing that you may need to store or send to other services.
Because REST systems interact through standard operations on resources, they do not rely on the implementation of the interfaces.
These constrains help RESTful applications achieve reliability, quick performance, and scalability, as components can be managed, updated, and reused without affecting the system as a whole, even during operation of the system.
Communication between Client and Server
In the REST architecture, clients send request to retrieve of modify resources, and servers send responses to these requests.
Making Requests
A request generally consist of:
- an HTTP verb, which defines what kind of operation to perform
- a header, which allows the client to pass along information about the request
- a path to a resource
- an optional message body containing data
REST does not rely on HTTP only. It can be implemented using other protocols, but it seems that HTTP won that battle by a far margin, and you will hardly find the REST implementation using other protocols.
HTTP verbs
There are 4 basic HTTP verbs we use in requests to interact with resources in a REST system:
- GET — retrieve a specific resource (by id) or a collection of resources
- POST — create a new resource
- PUT — update a specific resource (by id)
- DELETE — remove a specific resource by id
Headers and Accept Parameters
In the header of the request, the client sends the type of content that it is
able to receive from the server. This is called the Accept
field, and it
ensures that the server does not send data that cannot be understood or
processed by the client. The options for types of content are MIME Types.
MIME Types, used to specify the content types in the Accept
field, consist of
a type
and a subtype
separated by a slash (/).
For example, a text file containing HTML would be specified with the type
text/html
. If this text file contained CSS instead, it would be specified as
text/css
. A generic text file would be denoted as text/plain
. This default
value is not a catch-all, if a client is expecting text/css
and receives
text/plain
, it will not be able to recognize the content.
Other types and commonly used subtypes:
image
—image/png
,image/jpeg
,image/gif
audio
—audio/waw
,image/mpeg
video
—vides/mp4
,video/ogg
application
—application/json
,application/pdf
,application/xml
,application/octect-stream
A client accessing a resource with id
23 in an articles
resource on a server
might send a GET request like this:
GET /articles/23
Accept: text/html, application/xhtml
Paths
Request must contain a path to a resource that the operation should be performed on. In RESTful APIs, paths should be designed to help the client know what is going on.
Conventionally, the first part of the path should be the plural form of the resource. This keeps nested paths simple to read and easy to understand.
A path like onlinestore.com/customers/223/orders/12
is clear in what it points
to, even if you’ve never seen this specific path before, because it is
hierarchical and descriptive. We can see that we are accessing the order with
id
12 for the customer with id
223.
Paths should contain the information necessary to locate a resource with the degree of specificity needed.
When referring to a list or collection of resources, it is unnecessary to add an
id
to a POST request as the server will generate an id
for the new object,
e.g onlinestore.com/customers
will return the list of customers as an object
with an id
generated by the server.
If we are trying to access a single resource, we would need to specify and id
to the path. For example:
GET onlinestore.com/customers/:id
— retrieves the item in thecustomers
resource with theid
specified.DELETE onlinestore.com/customers/:id
— deletes the item incustomers
resource with theid
specified.
Sending Responses
Content Types
In cases where the server is sending a data payload1 to the client, the
server must include a content-type
in the header of the response. This
content-type
header field alerts the client to the type of data it is sending
in the response body.
The content types are MIME Types, just as they are in the accept
field of the
request header. The content-type
that the server send back in the response
should be one of the options that the client specified in the accept
field of
the request, e.g.
Client Request:
GET /articles/23 HTTP/1.1
Accept: text/html, application/xhtml
Possible Server Response:
HTTP/1.1 200 (OK)
Content-Type: text/html
This would signify that the content requested is being returned in the response
body with content-type
of text/html
, which the client said is able to
process.
Response Codes
Responses from the server contain status codes to alert the client to information about the success of the operation. As a developer, isn’t necessary to know every status code, but you should know the most common ones and how they are used:
Status Code | Meaning |
---|---|
200 (OK) | Standard response for successful HTTP request. |
201 (CREATED) | Standard response for an HTTP request that resulted in an item being successfully created. |
204 (NO CONTENT) | Standard Response for successful HTTP requests where nothing is being returned in the response body. |
400 (BAD REQUEST) | Request cannot be processed because of bad request syntax, excessive size, or another client error. |
403 (FORBIDDEN) | Client does not have permission to access this resource. |
404 (NOT FOUND) | The resource could not be found at this time. Is is possible that is was deleted, or does not exist yet. |
500 (INTERNAL SERVER ERROR) | The generic answer for an unexpected failure if there is no more specific information available. |
For each HTTP verb, there are expected status codes a server should return upon success:
- GET — return 200 (OK)
- POST — return 201 (CREATED)
- PUT — return 200 (OK)
- DELETE — return 204(NO CONTENT). If the operation fails, return the most specific status code possible corresponding to the problem that was encountered.
Examples of Requests and Responses
Let’s say we have an application that allows you to view, create, edit and
delete customers and orders for a small online store hosted at
onlinestore.com
. An HTTP API that allows a client to perform these functions,
would look like:
-
View all customers
Request:
GET http://onlinestore.com/customers Accept: application/json
Possible Response:
Status Code: 200 (OK) Content-type: application/json <!-- followed by the cusotmers data in application/json format -->
- Create a new customer
Request:
POST http://onlinestore.com/customers Body: { "customer": { "name" : "Scylla Buss" "email" : "scylla.buss@codeacademy.org" } }
Response: the server created an
id
for the object and returns it back to the client201 (CREATED) Content-type: application/json
- View a single customer
Request:
GET http://onlinestore.com/customers/123 Accept: application/json
Possible Response:
Status Code: 200 (OK) Content-type: application/json <!-- followed by the data of customer with id 123 in application/json format. -->
-
Update a customer by PUTing the new data:
Request:
PUT http://onlinestore.com/customers/123 Body: { "customers": { "name" : "Scylla Buss" "email" : "scyllabuss1@codeacademy.com" } }
Possible Response: status code and the object after the update
Status Code: 200 (OK) Content-type: application/json
-
Delete a customer:
Request:
DELETE http://onlinestore.com/customers/123
Response: notify that the customer with
id
123 had been deletedStatus code: 204 (NO CONTENT)
- Source: Codeacademy
- CRUD
-
In computing and telecommunications, the payload is the part of transmitted data that is the actual intended message. Headers and metadata are sent only to enable payload delivery ↩