Introduction to
REST
Maël Gargadennec
Freelance
What is (not) REST ?
JSON + HTTP
JSON is just one widely spread format
HTTP is a protocol
CRUD
It's not database over HTTP.
It's the state management of your system and its component parts over a given protocol.
Swagger
No. Just no.
Curl, Postman, HAL Browser, ...
A set of best practices
It's a set of constraints you apply onto your system.
A Silver Bullet
Additional payload
Multiple request/responses cycles
A little bit more complex to write
What is REST ?
An architectural style
described by Roy Thomas Fielding in his 2000 thesis
"Architectural Styles and the Design of Network-based Software Architectures"
“By using a stateless protocol and standard operations, REST systems aim for fast performance, reliability, and the ability to grow, by re-using components that can be managed and updated without affecting the system as a whole, even while it is running.”
Uniform Interface | Cacheable |
---|---|
Client-Server | Layered system |
Stateless | Code on demand |
Defines a set of constraints to follow to gain these above benefits
described by Roy Thomas Fielding in his 2000 thesis
"Architectural Styles and the Design of Network-based Software Architectures"
“By using a stateless protocol and standard operations, REST systems aim for fast performance, reliability, and the ability to grow, by re-using components that can be managed and updated without affecting the system as a whole, even while it is running.”
Uniform Interface | Cacheable |
---|---|
Client-Server | Layered system |
Stateless | Code on demand |
Defines a set of constraints to follow to gain these above benefits
Uniform interface
Identification of resources
Individual resources are identified uniquely in requests.
Resources are conceptually different from the representation sent to the client.
Manipulation of resources through their representations
The resource representation, including metadata, is enough to manipulate the resource.
Self-descriptive messages
Each message contains all informations needed by the client to process it.
(cacheability, content-type, available actions...)
Hypermedia as the engine of application state (HATEOAS)
Clients make state transitions on resources only depending on the server-side provided hypermedia links. They do not assume any particular action not present in the links to be available.
Client-Server
Request / Response
The client sends a request.
The server answers with a response.
Independent systems
No shared resources or codebase between the two systems.
Stateless
No saved client state on server
The server does not keep any information on client state after the request has been fully processed.
Each request in an independent call.
Authentication / Authorization
Each request must contains all authentication and authorization credentials.
Cacheable
Cache controls
The server provides mechanisms and metadata for the client to know :
* if the response can be cached
* by who (private/public)
* for how long
* if it must be invalidated / refreshed
Examples
The Cache-Control HTTP header.
Etags
Advantages
- Reduce bandwidth
- Reduce latency
- Reduce load on servers
- Hide network failures
Layered System
Intermediaries
A RESTful system can add a number of intermediaries between the client and the end-server without changing the interface between components (proxies, gateways, firewall, caches, ...)
Example
An API can be deployed on multiple servers A, A', A'', A'''.
Data can be stored on server B.
An authorization server can be deployed on server C.
Load balancers can be deployed on server D
The client won't know of all theses intermediaries and cluster topologies. They'll be evolving without impacting the client calls working.
Code on demand
(optional)
An architectural style
Richardson maturity model
Focus on HATEOAS
HAL
JSON-LD
collection+JSON,
SIREN
Simple specification
application/hal+json
application/hal+xml
Advantages
Human-readable
Flexible
Links to human textual documentation with CURIEs
Easy to implement
Easy to parse and use
Easy to extend
Demonstration
Server side
with spring-hateoas
ResourceSupport
Resource
Resources
PagedResources
Link
ResourceAssembler
PagedResourceAssembler
ControllerLinkBuilder
RelProvider
EntityLinks
CurieProvider
JAXB / Jackson support
Server side
with spring-hateoas
class PersonResource extends ResourceSupport {
String firstname;
String lastname;
}
Creating a resource
//Resource now has hypermedia capabilities
PersonResource resource = new PersonResource();
resource.firstname = "Dave";
resource.lastname = "Matthews";
resource.add(new Link(...));
//JSON rendering as
{
"firstname" : "Dave",
"lastname" : "Matthews",
_"links" : [
{
"rel" : "self",
"href" : "http://myhost/people"
}
]
}
class PersonResource
extends Resource<PersonResourceState> {
}
//Resource now has hypermedia capabilities
PersonResourceState state
= new PersonResourceState("Dave", "Matthews");
PersonResource resource = new PersonResource(state);
resource.add(new Link(...));
Server side
with spring-hateoas
Creating a resource with an assembler
class PersonResourceAssembler extends ResourceAssemblerSupport<Person, PersonResource> {
public PersonResourceAssembler() {
super(PersonController.class, PersonResource.class);
}
@Override
public PersonResource toResource(Person person) {
PersonResource resource = createResource(person);
// … do further mapping
// … add links
return resource;
}
}
@RestController
@RequestMapping("/persons")
class PersonController {
final PersonResourceAssembler assembler;
final PersonService service;
@GetMapping
public Resources<PersonResource> persons() {
return new Resources<>(this.service.getAll().stream().map(this.assembler::toResource).collect(Collectors.toList()));
}
@GetMapping("/{id}")
public PersonResource person(@PathVariable Long id)(
return assembler.toResource(service.getOne(id));
)
}
Server side
with spring-hateoas
Creating a link
import static org.sfw.hateoas.mvc.ControllerLinkBuilder.*;
//Direct creation
Link link = new Link("http://localhost:8080/something", "any-relation");
//Link to specific controller resource
Link link = linkTo(PersonController.class).slash(2L).withRel("person");
//Link to controller method with template parameters
Link link = linkTo(methodOn(PersonController.class).show(null)).withRel("person");
//Link to controller method with set parameters
Link link = linkTo(methodOn(PersonController.class).show(2L)).withSelfRel();
//Link to specific resource list
EntityLinks links = ...;
LinkBuilder linkBuilder = links.linkToResource(PersonResource.class).withRel("persons");
Link link = links.linkToSingleResource(PersonResource.class, 1L);
Client side
with angular-hal-client
Resource
ResourceInterceptor
HalResourceClient
Factories
Configuration
Client side
with angular-hal-client
Resource
ResourceInterceptor
HalResourceClient
Factories
Configuration
rest-api-hateoas
By Maël Gargadennec
rest-api-hateoas
- 236