This is a session given by Filippos Vasilakis at Nordic APIs 2016 Platform Summit on October 26th, in Stockholm Sweden.
Description:
We will go through what a modern REST API is, see what the least features we should provide to the clients are, how we can test it super fast (because testing APIs can be very time consuming!), and how we can optimize it’s performance. The talk will not be bound to any specific API spec (JSONAPI, Serien, HAL etc) but will go though all the principles of a modern REST API. However we will challenge Roy Fieldings’s thesis on REST APIs (is it still valid? we will see!) along with current specs which are based on Roy’s thesis (like JSONAPI spec) especially when high performance part of the API design.
3. Roy Fielding's REST
identification of resources
manipulation of resources through representations
self-descriptive messages
hypermedia as the engine of application state.
HATOEAS
REST is defined by four interface constraints
(taken from Roy's thesis)
5. Roy Fielding's REST
provide links that client must use
response (with links) reflects the UI
That would mean:
different response for different
devices
Accept header
Content-Type header
6. APIs of a business in 2016
develop a flexible API
one to fit all strategy
split content in resources
provide links at runtime that client
could need
client's UI could render a subset of
them
provide detailed documentation
7. Roy Fielding's REST
“ A REST API should be entered with no prior knowledge beyond the
initial URI (bookmark) and set of standardized media types that are
appropriate for the intended audience (i.e., expected to be understood
by any client that might use the API).
We are already sliding away from Roy's idea..
8. Modern APIs
Provide a ORM to client over HTTP
Sparse fields
Granular permissions
Associations on demand
Hypermedia Driven
Resource
+
Collection
Collection
}Sorting & pagination
Filtering collections
Aggregation queries
}
10. API specs on 2016
{
"data": [
{
"id": "288",
"type": "microposts",
"attributes": {
"content": "Nordic APIs now live!",
"user-id": 1,
"created-at": "2016-10-06T20:45:12Z",
"updated-at": "2016-10-06T11:02:12Z"
},
"relationships": {
"user": {
"links": {
"self": "/api/v1/users/1"
}
}
}
}
],
"links": {
"self": "/api/v1/microposts?page[number]=1&page[size]=1",
"next": "/api/v1/microposts?page[number]=2&page[size]=1",
"last": "/api/v1/microposts?page[number]=3&page[size]=1"
}
}
JSONAPI
Some links (no URI templates)
No actions
No info on available attributes
No data types of attributes
No descriptions/helpful
messages
11. API specs on 2016
{
"data": {
"id": "1",
"type": "users",
"attributes": {
"name": "Filippos Vasilakis",
"email": "vasilakisfil@gmail.com",
"created-at": "2016-10-06T20:46:55Z",
"microposts-count": 50,
"followers-count": 38,
"followings-count": 49
},
"relationships": {
"microposts": {
"links": {
"related": "/api/v1/microposts?user_id=1"
}
}
}
}
JSONAPI
Some links (no URI templates)
No actions
No info on available attributes
No data types of attributes
No descriptions/helpful
messages
12. API specs on 2016
{
"_links":{
"self":{
"href":"/api/v1/microposts"
},
"curries":[
{
"name":"ea",
"href":"http://example.com/docs/rels/{rel}",
"templated":true
}
]
},
"_embedded":{
"micropost":[
{
"_links":{
"self":{
"href":"/api/v1/microposts/{id}"
},
"user":{
"href":"/api/v1/users/{user_id}"
}
},
"id": 288,
"content":"Nordic APIs is not live!",
"user_id":6,
"created_at":"2016-10-06T20:45:12.693Z",
"updated_at":"2016-10-06T11:02:12.693Z"
}
]
}
}
HAL
Links (no URI templates)
No actions
No info on available attributes
No data types of attributes
Some descriptions/helpful
messages
13. API specs on 2016
{
"_links": {
"self": {
"href": "/api/v1/users/{id}"
},
"microposts": {
"href": "/api/v1/microposts/user_id={id}",
"templated": true
}
},
"id": "1",
"name": "Filippos Vasilakis",
"email": "vasilakisfil@gmail.com",
"created-at": "2016-10-06T20:46:55Z",
"microposts-count": 50,
"followers-count": 38,
"followings-count": 49
}
HAL
Links (no URI templates)
No actions
No info on available attributes
No data types of attributes
Some descriptions/helpful
messages
14. API specs on 2016
{
"links":[{ "rel": ["self"], "href": "/api/v1/microposts" }],
"entities":[
{
"links":[
{"rel":["self"], "href":"/api/v1/microposts/288"},
{"rel":["user"], "href":"/api/v1/users/1"}
],
"rel":[
"micropost"
],
"class":[
"micropost"
],
"properties":{
"content":"Nordic APIs is now live!",
"user_id":1,
"created_at":"2016-10-06T20:45:12.693Z",
"updated_at":"2016-10-06T11:02:12.693Z"
}
},
],
"actions":[
{
"name": "create-micropost",
"title": "Create Micropost",
"method": "POST",
"href": "http://myapi.com/microposts",
"type": "application/json",
"fields": [
{ "name": "context", "type": "text" }
]
}
],
"class":[
"microposts"
]
}
Siren
Links (no URI templates)
Actions
No info on available attributes
No data types of attributes
Some descriptions/helpful
messages
15. API specs on 2016
{
"links":[
{
"rel":[
"self"
],
"href":"/api/v1/users/1"
},
{
"rel":[
"microposts"
],
"href":"/api/v1/microposts?user_id=1"
}
],
"class":[
"user"
],
"actions":[
],
"properties":{
"id":"1",
"name":"Filippos Vasilakis",
"email":"vasilakisfil@gmail.com",
"created-at":"2016-10-06T20:46:55Z",
"microposts-count":50,
"followers-count":38,
"followings-count":49
}
}
Siren
Links (no URI templates)
Actions
No info on available attributes
No data types of attributes
Some descriptions/helpful
messages
16. 1. Available attributes with data types
2. Links (with URI templates)
available resources
available associations
3. Available actions
Hypermedia Driven APIs
Performance issues
Complexity
Possibly useless information
Parsing these info at runtime leads to:
17. API specs on 2006
{
"id":"1",
"name":"Filippos Vasilakis",
"email":"vasilakisfil@gmail.com",
"created-at":"2016-10-06T20:46:55Z",
"microposts-count":50,
"followers-count":38,
"followings-count":49
}
I miss my good old API
{
"microposts":[
{
"content":"Nordic APIs is now live!",
"user_id":1,
"created_at":"2016-10-06T20:45:12.693Z",
"updated_at":"2016-10-06T11:02:12.693Z"
}
]
}
Is it possible to have an API like that today?
18. APIs for the future
Separate hypermedia and documentation from actual data
Idea
How?
JSON Hyper Schemas + HTTP OPTIONS on the endpoint
API introspection
19. APIs for the future
HTTP GET https://my-api.com/api/v1/users/1
protocol
method host resource
unique
20. APIs for the future
https://my-api.com/api/v1/users/1
}
GET
POST
PUT/PATCH
DELETE
{HTTP
https://my-api.com/api/v1/users
}
GET
POST
PUT/PATCH
DELETE
{HTTP
21. APIs for the future
Develop a flexible API
one to fit all strategy
Split content in resources
provide links at runtime that client
could need
client's UI could render a subset of
them
provide detailed documentation
provide automated documentation
22. APIs for the future
Provide automated documentation
JSON Schemas!
“ JSON Schema specifies a JSON-based format to define the structure
of JSON data for validation, documentation, and interaction control. A
JSON Schema provides a contract for the JSON data required by a given
application, and how that data can be modified.
26. API specs for the future
JSON Hyper-Schema
{
"$schema":"http://json-schema.org/draft-04/schema#",
"type":"object",
"properties":{
"microposts":{
"type":"array",
"uniqueItems":true,
"items":{
"type":"object",
"properties":{
}
}
},
"links":[
{
"rel":"user",
"method":"GET",
"href":"/api/v1/user/{user_id}"
}
]
}
}
2. Links (using URI templates)
27. API specs for the future
JSON Hyper-Schema
{
"$schema":"http://json-schema.org/draft-04/schema#",
"type":"object",
"properties":{
"microposts":{
"type":"array",
"uniqueItems":false,
"items":{
"type":"object",
"properties":{...}
}
},
"links":[
{
"rel":"user",
"method":"GET",
"href":"/api/v1/user/{user_id}"
}, {
"encType": "application/json",
"method": "POST",
"href": "/microposts",
"properties": {
"content": {
"description": "Content of the micropost.",
"type": "string",
"minLength": 1,
"maxLength": 160
}
}
}
]
}
}
3. Available actions
28. 1. Available attributes with data types
2. Links (with URI templates)
available resources
available associations
3. Available actions
Hypermedia Driven APIs
Better performance
Documentation driven
Testable input/output for both client and
server
Still online but on demand:
29. APIs for the future
Specs that seprate hypermedia from data model and data
Open API (also known as Swagger)
A spec for writting a documentation
Heavy uses JSON Schemas
Complex but very robust
it can even describe headers
Targeted for offline documetation generation and
server side code generation
limtations on the client side
30. APIs for the future
Specs that seprate hypermedia from data model and data
Hydra Spec (JSON-LD + Schema.org + Hydra core Vocabulary)
Links
Attributes (no data types)
Actions
Context (semantics in Social Web)
31. APIs for the future
Specs that seprate hypermedia from data model and data
GraphQL
No links :(
Attributes + data types ( calls it introspection)
Actions (calls it mutations)
Covered on the next talk!