====== REST - Representational state transfer ======
===== Methods =====
Dies ist eine Konvention (kein Standart) zur Anfrage der Daten via HTTP.
Es werden Methoden übergeben:
| | GET | POST | PUT | DELETE| PATCH|
|Safe | x | | | | |
|Idempotent| x | | x | x | |
Idempotence means that executing the funciton more than once has the same effect as if I would execute it more than once.
A good describtion is here: \\
https://restfulapi.net/idempotent-rest-apis/
|GET| Just retrieves the resource, without changing it.|
|DELETE| Removes a concrete resource. When repeated - does the same. So resources does not exist after removal.|
|POST| Creates a concrete resource, which will be a **CHILD** of the given URL. POST http://api.ex.com/tales/7dwarfs/ {name=oink..} |
|PUT| Creates a concrete resource, which will be reachable under the **GIVEN CONCRETE URL**. PUT http://api.ex.com/tales/7dwarfs/oink {name=oink..} |
|PATCH| Changes the resource. The change may define the required state, which makes it NON idempotent. From Name=John to Name=Gargantua. After repeated applying the name will be Gargantua and patch will fail, since it should change "from Name=John" |
===== Maturity of REST ======
{{https://martinfowler.com/articles/images/richardsonMaturityModel/overview.png}}
==== What makes REST architecture mature? 4 steps ====
https://martinfowler.com/articles/richardsonMaturityModel.html
=== 0. Swarm of POX - Plain old XML ===
Characteristics:
* exchanging some XML / JSON with **some Service like /appointmentService**
* tunneling a mechanism for an own RPC - remote interaction mechanism
Request:
POST /appointmentService HTTP/1.1
[various other headers]
Response:
HTTP/1.1 200 OK
[various headers]
=== Glossary ===
| Compound Documents |
To reduce the number of HTTP requests, servers MAY allow responses that include related resources along with the requested primary resources. Such responses are called “compound documents”.
https://jsonapi.org/format/#document-compound-documents
|
|Sparse Fieldsets| A client MAY request that an endpoint return only specific fields in the response on a per-type basis by including a fields[TYPE] parameter. GET /articles?include=author&fields[articles]=title,body&fields[people]=name` |
=== 1. Resources ===
Characteristics:
* tunneling a mechanism for an own RPC - remote interaction mechanism. **But to special URIs** - not one service.
* **using Resources**. On the URI too like **/doctors/mjones** or **/slots/1234/appointment**. Collections are for listing resources. Concrete resources are for getting details. \\ Level 1 tackles the question of handling complexity by using divide and conquer, breaking a large service endpoint down into multiple resources.
Request:
POST /doctors/mjones
[various other headers]
Response:
HTTP/1.1 200 OK
[various headers]
Request:
POST /slots/1234
Response:
HTTP/1.1 200 OK
=== 2. Using HTTP Verbs ===
Characteristics:
* tunneling a mechanism for an own RPC - remote interaction mechanism. **But to special URIs** - not one service.
* **using Resources**. On the URI too like **/doctors/mjones** or **/slots/1234/appointment**. Collections are for listing resources. Concrete resources are for getting details.
* **Using GET, POST, PUT, DELETE, PATCH - similarly to HTTP**. GET is safe. POST, DELETE, PATCH are not. \\ Level 2 introduces a standard set of verbs so that we handle similar situations in the same way, removing unnecessary variation.
Request:
GET /slots/?status=open&doctor=mjones
Response:
HTTP/1.1 200 OK
Request:
POST /doctors/mjones/slots/
Response:
HTTP/1.1 200 OK
HTTP/1.1 409 Conflict
=== 3. HATEOAS - Hypermedia As The Engine Of Application State ===
Characteristics:
* tunneling a mechanism for an own RPC - remote interaction mechanism. **But to special URIs** - not one service.
* **using Resources**. On the URI too like **/doctors/mjones** or **/slots/1234/appointment**. Collections are for listing resources. Concrete resources are for getting details.
* **Using GET, POST, PUT, DELETE, PATCH - similarly to HTTP**. GET is safe. POST, DELETE, PATCH are not.
* The **references** to **next steps** are **embedded dynamically** into the response. Allowing to develop the client separately from the server. It allows the server to change its URI scheme without breaking clients. https://ru.wikipedia.org/wiki/HATEOAS \\ Level 3 introduces discoverability, providing a way of making a protocol more self-documenting.
Request
POST /slots/1234 HTTP/1.1
Response
HTTP/1.1 201 Created
Location: http://royalhope.nhs.uk/slots/1234/appointment
==== HAL - Hypertext Applicaiton Language ====
**REST** is a concept of application architecture. Its multiple maturity states are defined above: Stack of POX, Ressource, Verbs etc.
**HATEOAS** is a concept of application architecture. It defines the way in which application clients interact with the server, by navigating hypermedia links they find inside resource models returned by the server.
To implement HATEOAS you need some standard way of representing resources, that will contain hypermedia information (links to related resources), for example, something like this:
**HAL** is one of such standards. It is a specific format of resource presentation, that can be used to implement HATEOAS.
* HAL Introduction: http://javaeeeee.blogspot.ch/2015/02/introduction-to-hypertext-application.html
* HAL browser: http://api.m.ox.ac.uk/browser/#/
===== REST API Example =====
==== High level Structure ====
The structure of the responce:
errors
data
attributes
links
self
related
relationships
included
meta
==== Responses ====
GET http://api.ex.com/tales/7dwarfs/1
{
data{
id: 1,
type: characters,
attributes{
name: "oink",
size: "1m",
race: "dwarf"
},
links{
self: "http://api.ex.com/v1/tales/7dwarfs/characters/1"
}
}
}
GET http://api.ex.com/tales/7dwarfs/8
{
data{
id: 8,
type: characters,
attributes{
name: "snowwhite",
size: "1.7m",
race: "human"
},
links{
self: "http://api.ex.com/v1/tales/7dwarfs/characters/8"
}
}
}
GET http://api.ex.com/tales/7dwarfs/
{
data{
id: 7dwarfs,
type: tales,
attributes{
name: "7 dwarfs"
},
links{
self: "http://api.ex.com/v1/tales/7dwarfs"
},
relationships{
housekeeper: {
data: {
id: 8,
type: "characters",
},
links: {
self: "http://api.ex.com/v1/tales/7dwarfs/relationships/housekeeper",
related: "http://api.ex.com/v1/tales/7dwarfs/characters/8",
}
}
}
}
}
GET "http://api.ex.com/v1/tales/7dwarfs/characters?limit=5;offset=5",
{
data: {
characters: [
{ id:6, name: "gloink" }
{ id:7, name: ".." }
{ id:8, name: "snow white" }
{ id:9, name: ".." }
{ id:10, name: ".." }
],
links: {
first: "http://api.ex.com/v1/tales/7dwarfs/characters/1",
prev: "http://api.ex.com/v1/tales/7dwarfs/characters?offset=0;limit=5",
next: "http://api.ex.com/v1/tales/7dwarfs/characters?offset=10;limit=5",
last: "http://api.ex.com/v1/tales/7dwarfs/characters/25"
}
}
}
== CURIES ==
Cut URI - an approach to reduce the long URLs
GET http: //api.ex.com/tales/7dwarfs/1{
data{
id: 1,
type: characters,
attributes{
name: "oink",
size: "1m",
race: "dwarf"
},
curies{
{
name: "root",
href: "http://api.ex.com/v1/"
},
links{
self: "root:tales/7dwarfs/characters/1",
prev: "root:tales/7dwarfs/characters/0",
next: "root:tales/7dwarfs/characters/2",
}
}
}