32
Sliding away from Roy Fielding's REST model Filippos Vasilakis Web Engineer at Kollegorna

Sliding away from Roy Fielding's REST model (Filippos Vasilakis)

Embed Size (px)

Citation preview

Sliding away fromRoy Fielding'sREST model

Filippos VasilakisWeb Engineer at Kollegorna

Topics

1. REST defined by Roy Fielding2. REST in practice3. Introspected REST

Roy Fielding's REST

identification of resourcesmanipulation of resources through representationsself-descriptive messageshypermedia as the engine of application state.

HATOEAS

REST is defined by four interface constraints

(taken from Roy's thesis)

Roy Fielding's REST

provide links that client must useserver response (with links) reflects the UI

Roy Fielding's REST

provide links that client must useresponse (with links) reflects the UI

That would mean:

different response for differentdevices

Accept headerContent-Type header

APIs of a business in 2016

develop a flexible APIone to fit all strategy

split content in resourcesprovide links at runtime that clientcould need

client's UI could render a subset ofthem

provide detailed documentation

Roy Fielding's REST

“ A REST API should be entered with no prior knowledge beyond theinitial URI (bookmark) and set of standardized media types that are

appropriate for the intended audience (i.e., expected to be understoodby any client that might use the API).

We are already sliding away from Roy's idea..

Modern APIs

Provide a ORM to client over HTTP

Sparse fieldsGranular permissionsAssociations on demandHypermedia Driven

Resource+

Collection

Collection}Sorting & paginationFiltering collectionsAggregation queries

}

Hypermedia Driven{ "micropost": { "id": 3031, "description": "Hey there!", "links": { "self": "/api/v1/microposts/3031", "comments": "/api/v1/microposts/3031/comments", "user": "/api/v1/users/18" }, "likes": [{ "user_id": 18, "video_id": 3031, "user": { "id": 18, "username": "filippos", "name": "Filippos Vasilakis", "avatar": "4c657cfe-116d-4f3f-694d-9164e5294e72.jpg" }, "links":{ "micropost": "/api/v1/micropost/3031", "user": "/api/v1/users/18" } }] }}

Is it only links?

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 actionsNo info on available attributesNo data types of attributesNo descriptions/helpfulmessages

API specs on 2016

{ "data": { "id": "1", "type": "users", "attributes": { "name": "Filippos Vasilakis", "email": "[email protected]", "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 actionsNo info on available attributesNo data types of attributesNo descriptions/helpfulmessages

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 actionsNo info on available attributesNo data types of attributesSome descriptions/helpfulmessages

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": "[email protected]", "created-at": "2016-10-06T20:46:55Z", "microposts-count": 50, "followers-count": 38, "followings-count": 49}

HAL

Links (no URI templates)No actionsNo info on available attributesNo data types of attributesSome descriptions/helpfulmessages

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)ActionsNo info on available attributesNo data types of attributesSome descriptions/helpfulmessages

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":"[email protected]", "created-at":"2016-10-06T20:46:55Z", "microposts-count":50, "followers-count":38, "followings-count":49 }}

Siren

Links (no URI templates)ActionsNo info on available attributesNo data types of attributesSome descriptions/helpfulmessages

1. Available attributes with data types2. Links (with URI templates)

available resourcesavailable associations

3. Available actions

Hypermedia Driven APIs

Performance issuesComplexityPossibly useless information

Parsing these info at runtime leads to:

API specs on 2006

{ "id":"1", "name":"Filippos Vasilakis", "email":"[email protected]", "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?

APIs for the future

Separate hypermedia and documentation from actual data

Idea

How?

JSON Hyper Schemas + HTTP OPTIONS on the endpoint

API introspection

APIs for the future

HTTP GET https://my-api.com/api/v1/users/1

protocolmethod host resource

unique

APIs for the future

https://my-api.com/api/v1/users/1}GETPOST

PUT/PATCHDELETE{HTTP

https://my-api.com/api/v1/users}GETPOST

PUT/PATCHDELETE{HTTP

APIs for the future

Develop a flexible APIone to fit all strategy

Split content in resourcesprovide links at runtime that clientcould need

client's UI could render a subset ofthem

provide detailed documentation provide automated documentation

APIs for the future

Provide automated documentation

JSON Schemas!

“ JSON Schema specifies a JSON-based format to define the structureof JSON data for validation, documentation, and interaction control. AJSON Schema provides a contract for the JSON data required by a given

application, and how that data can be modified.

API specs for the future

{ "id":"1", "name":"Filippos Vasilakis", "email":"[email protected]", "created-at":"2016-10-06T20:46:55Z", "microposts-count":50, "followers-count":38, "followings-count":49}

{ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "email": { "type": "string" }, "created-at": { "type": "string" }, "microposts-count": { "type": "integer" }, "followers-count": { "type": "integer" }, "followings-count": { "type": "integer" } }}

1. Available attributes with data types

API specs for the future

{ "id":"1", "name":"Filippos Vasilakis", "email":"[email protected]", "created-at":"2016-10-06T20:46:55Z", "microposts-count":50, "followers-count":38, "followings-count":49}

{ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "id": { "type": "string", "minimum": "1" }, "name": { "type": "string", "pattern": "^[a-zA-Z ]*$", "minLength": 5, "maxLength": 120 }, "email": { "type": "string", "format": "email" }, "created-at": { "type": "string", "format": "date-time" }, "microposts-count": { "type": "integer", "format": "date-time" }, "followers-count": { "type": "integer", "minimum": "1" }, "followings-count": { "type": "integer", "minimum": "1" } }}

1. Available attributes with data types

API specs for the future

{ "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" } ]}

{ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "microposts": { "type": "array", "uniqueItems": true, "items": { "type": "object", "properties": { "content": { "type": "string", "minLength": 1, "maxLength": 160 }, "user_id": { "type": "integer", "multipleOf": 1, "minimum": 1, }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } } } }}

1. Available attributes with data types

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)

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

1. Available attributes with data types2. Links (with URI templates)

available resourcesavailable associations

3. Available actions

Hypermedia Driven APIs

Better performanceDocumentation drivenTestable input/output for both client andserver

Still online but on demand:

APIs for the futureSpecs that seprate hypermedia from data model and data

Open API (also known as Swagger)

A spec for writting a documentationHeavy uses JSON SchemasComplex but very robust

it can even describe headersTargeted for offline documetation generation andserver side code generation

limtations on the client side

APIs for the futureSpecs that seprate hypermedia from data model and data

Hydra Spec (JSON-LD + Schema.org + Hydra core Vocabulary)

LinksAttributes (no data types)ActionsContext (semantics in Social Web)

APIs for the futureSpecs that seprate hypermedia from data model and data

GraphQLNo links :(Attributes + data types ( calls it introspection)Actions (calls it mutations)Covered on the next talk!

Sliding away fromRoy Fielding'sREST model

Thank you!