Joost Cassee
PyCon Sette, 15 April 2016
Painless Software
django-analytical
django-geckoboard
django-localeurl
angular-hypermedia
joost@cassee.net
@jcassee
jcassee.com
URI
http://example.com/ship/9334026
"An entity"
{
"name": "VOS PROMINENCE",
"imo": 9334026,
"type": "cargo"
}
Media Type
application/json
Profile
http://example.com/profiles/ship
"It is a ship"
The resource identified by http://example.com/ship/9334026
{
"name": "VOS PROMINENCE",
"imo": 9334026,
"type": "cargo"
}
and is represented as application/json by
has profile http://example.com/profiles/ship
A resource identified by a http/https URL
can be manipulated using HTTP methods
GET
PUT
DELETE
PATCH
POST
Retreive a representation
Store a representation
Delete a resource
(Partially) update a resource
"Process" a representation
Expose business logic as state manipulation
rocess
href
http://example.com/company/3342
"That entity over there"
{
"name": "VOS PROMINENCE",
"imo": 9334026,
"type": "cargo",
"ownerHref": "http://example.com/company/3342"
}
"That is the owner"
(semantics described by the profile)
Relation
http://example.com/relations/owner
"It has an owner"
The resource identified by http://example.com/ship/9334026
to the resource identified by http://example.com/company/3342
has relation http://example.com/relations/owner
Hypermedia Application Language
application/hal+json
{
"name": "VOS PROMINENCE",
"imo": 9334026,
"type": "cargo",
...
{
"name": "VOS PROMINENCE",
"imo": 9334026,
"type": "cargo",
"_links": {
"self": {
"href": "http://example.com/ship/9334026"
},
"profile": {
"href": "http://example.com/profiles/ship"
},
"http://example.com/relations/owner": {
"href": "http://example.com/company/3342"
}
},
...
{
...
"_embedded": {
"http://example.com/relations/owner": {
"name": "Vroon B.V.",
"_links": {
"self": {
"href": "http://example.com/company/3342"
},
"profile": {
"href": "http://example.com/profiles/company"
}
}
}
}
}
{
"_links": {
"rel": { "href": "uri" }
}
}
{
"property": "uri"
}
Hypertext As The Engine Of Application State
"Use links to traverse the API"
"It's not an API, it's a protocol!"
give you
require
{
"_links": {
"self": { "href": "http://example.com/users/john" },
"profile": { "href": "http://profiles.example.com/person" }
}
}
{
"_links": {
"self": { "href": "http://example.com/clients/4335/contact" },
"profile": { "href": "http://profiles.example.com/person" }
}
}
{
...
"_links": {
"self": {
"href": "http://example.com/ship/9334026"
},
"http://example.com/relations/owner": {
"href": "http://companies.example.com/3342"
}
}
}
{
"_links": {
"http://example.com/relations/owner": {
"href": "http://example.com/company/3342"
}
}
{
"_links": {
"http://example.com/relations/owner": {
"href": "http://companies.example.com/3342"
}
}
{
"_links" : {
"http://example.com/relations/owner" : {
"href" : "http://example.com/company/3342",
"deprecation": "http://example.com/docs/deprecated/owner.html"
},
"http://example.com/relations/ownership" : {
"href" : "http://example.com/ship/9334026/ownership/3"
}
}
}
Models
domain entities and business rules
Serializers
representation structure
Renderers
representation syntax
View(Set)s
resources
Media type
use HalRenderer
Profiles
defined by the Serializer
Relations
added by the View
Resources
are View(Set)s (using a Router)
Serializer
... using custom Router, ViewSets, Serializers
all working together: drf_hal module
too finegrained
Given
And
When
And
Then
a company named "Joost Shipping"
ship named "Providence" owned by "Joost Shipping"
you get the ship "Providence"
you follow the relation "ship-owner"
the response is ...
Getting information about companies that own ships
Get a ship's owner
Feature:
Scenario:
Gherkin language
Relish
Featurebook
Company
Ship
Ownership
Company
Ship
{
"_embedded": {
"http://rels.registronavale.com/ship-owner": {
"_links": {
"self": {
"href": "https://api.registronavale.com/company/1"
}
{
"_links": {
"http://rels.registronavale.com/owner-history": {
"href": "https://api-pr1.registronavale.com/ship-owners-history/12345"
},
"http://rels.registronavale.com/ship-owner": {
"deprecation": "http://apidocs.registronavale.com/deprecation/...",
"href": "https://api-pr1.registronavale.com/company/1"
}
Painless Software
Less pain, more fun