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