REST Architecture
What is REST?
Representational State Transfer
(Roy Fielding, 2000)
Architecture style
that defines a set of constraints and properties based on HTTP
Allow easy communication between computer systems on the Internet
REST provides a definition of a "resource"
For example, a web page (HTML) is a representation of a "resource" (URLs)
Often used in the development of web services
The key abstraction of information in REST is a resource. Any information that can be named can be a resource: a document or image, a temporal service (e.g. "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (e.g. a person), and so on.
- Roy Fielding's dissertation.
http://localhost:1234/users # the resource is a collection
http://localhost:1234/users/1 # the resource is a singleton
Example of REST resources
Also called REST endpoints (API)
Separation of Client / Server
In REST architecture, the implementation of the client and the implementation of the server can be done independently
Different clients / type of clients can hit the same server by using the REST endpoints, perform the same actions and receive the same responses
SEPARATION OF CONCERN 🙌
We separate the user interface concerns from the data storage concernsÂ
Only thing to agree on: message format
Statelessness
In REST, the server does not store any state about the client session on the server side
Each client request must contain all necessary information so that the server understands it
(The server should not need the previous request to understand the current request...)
Scaling: from 10 to Millions of users (multiple servers, no session related dependency)
Less complex: no server side state synchronization logic
Advantages
Easy cache: only for GET HTTP requests (idempotent) 😅 https://twitter.com/rombulow/status/990684453734203392
Resources and representations
A resource can be a singleton or a collection
# collection
https://api-example/movies
# singleton
https://api-example/movies/{id}
# sub-collection
https://api-example/movies/{id}/actors
# controller (executable functions)
https://api-example/movies/{id}/tickets/{id}/checkout
Resource naming guide 🙌
👉 Use nouns for collections, singletons and verbs for controllers
👉 Use forward slash (/) for hierarchical relationships
👉 Use hyphens (-) to improve readability
JSON representation
{
"id": "1",
"title": "Black Panther",
"release": "2019-01-29T00:00:00Z",
"actors": [
"Chadwick Boseman",
"Michael B. Jordan",
"Lupita Nyong'o"
]
}
XML representation
<?xml version="1.0" encoding="UTF-8" ?>
<id>1</id>
<title>Black Panther</title>
<release>2019-01-29T00:00:00Z</release>
<actors>Chadwick Boseman</actors>
<actors>Michael B. Jordan</actors>
<actors>Lupita Nyong'o</actors>
HTTP Verbs
https://api-example/movies
GET
Retrieve the entire collection of movies
Retrieve a single movie (id = 1)
https://api-example/movies/1
https://api-example/movies
POST
Create a new movie entryÂ
Not generally used for singleton resource
PUT
https://api-example/movies
Replace the entire collection with a new collection
Replace the addressed movie of the collection
https://api-example/movies/1
DELETE
https://api-example/movies
Delete the entire collection of movies
Delete the addressed movie of the collection
https://api-example/movies/1
Build a REST API with node & Express
$ yarn add express
Installing Express
$ npm install express --save
// file app.js
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello, World!'));
app.listen(3000, () => {
console.log('Listening on port 3000!');
});
Hello, World!
$ node ./app.js # then, load localhost:3000/ in a browser
Routing
How an application responds to a client request to a particular endpoint
Endpoint: a URI / path with a specific HTTP request method (GET, POST, PUT, DELETE)
app.method(path, handler);
Routing / GET
app.get('/movies', (req, res) => {
// fetch movies from DB, from JSON, ...
// send collection to `res` (response)
res.status(200).json(movies);
});
Routing / POST
app.post('/movies', (req, res) => {
const newMovie = req.body;
// add new movie from `req` (request) to collection
// send new movie to `res` (response)
res.status(201).json(newMovie);
});
// To parse json body (for POST / PUT)
const bodyParser = require('body-parser');
app.use(bodyParser.json());
Routing / PUT
app.put('/movies/:id', (req, res) => {
const movieId = req.params.id;
const movie = req.body;
// update movie from id in collection
// send updated movie to `res` (or nothing)
res.status(200).json(movie);
// or res.status(204);
});
Routing / DELETE
app.delete('/movies/:id', (req, res) => {
const movieId = req.params.id;
// delete movie from id in collection
// send response
res.status(200).json(deletedMovie);
// or res.status(204);
});
Middleware
A middleware is a function that has access to req, res objects and a next function. It can be called before each requests or before specific requests. It can perform any operations and call the next middleware function or stop the request-response cycle.
Middleware
const middleware = (req, res, next) => {
console.log('Time:', Date.now());
// calling next() to continue request-response cycle
next();
};
const app = express();
app.use(middleware);
The middleware function will be executed for all request endpoints
Middleware
const middleware = (req, res, next) => { ... };
const app = express();
app.get('/movies', middleware, (req, res) => {
// fetch all movies
res.json(movies);
});
The middleware function will be executed only for the "/movies"Â request endpoint
REST Architecture
By Nicolas Payot
REST Architecture
- 881