pragmatic hypermedia rest apis
Post on 07-Jan-2017
122 Views
Preview:
TRANSCRIPT
Paw
luckymarmot.com
The ultimate HTTP client for Mac
@mittsh
Micha Mazaheri
• Solving problems • Focus on UX
Pragmatic Hypermedia REST
Mike Amundsen: A Hypermedia Hero's Tale
What is hypermedia?
$ curl https://api.github.com { "current_user_url": "https://api.github.com/user", "code_search_url": "https://api.github.com/search/code?…", "events_url": "https://api.github.com/events", "feeds_url": "https://api.github.com/feeds", "followers_url": "https://api.github.com/user/followers", "following_url": "https://api.github.com/user/following{/target}", "repository_url": "https://api.github.com/repos/{owner}/{repo}",
... }
"repository_url": "https://api.github.com/repos/{owner}/{repo}",
$ curl https://api.github.com/repos/luckymarmot/paw { "id": 6778468, "name": "paw", "full_name": "luckymarmot/paw", "owner": { "login": "luckymarmot", "id": 3215332, "url": "https://api.github.com/users/luckymarmot", "html_url": "https://github.com/luckymarmot", ... }, "private": true, "html_url": "https://github.com/luckymarmot/paw", "description": "Paw", "fork": false, "url": "https://api.github.com/repos/luckymarmot/paw", "forks_url": "https://api.github.com/repos/luckymarmot/
"url": "https://api.github.com/users/luckymarmot",
It’s also about Describing Resources
JSON-LD• Linked Data • RDF • SPARQL (search) • Handle complex data sets
{ "name": "Jon Snow", "homepage": "http://jon-snow.winterfell/" }
{ "@type": "Person", "name": "Jon Snow", "homepage": "http://jon-snow.winterfell/" }
{ "@id": "http://me.example.com", "@type": "Person", "name": "Jon Snow", "homepage": "http://jon-snow.winterfell/" }
{ "@context": { "name": "http://xmlns.com/foaf/0.1/name", "homepage": { "@id": "http://xmlns.com/foaf/0.1/workplaceHomepage", "@type": "@id" }, "Person": "http://xmlns.com/foaf/0.1/Person" }, "@id": "http://me.example.com", "@type": "Person", "name": "Jon Snow", "homepage": "http://jon-snow.winterfell/" }
{ "@context": { "name": "http://xmlns.com/foaf/0.1/name", "homepage": { "@id": "http://xmlns.com/foaf/0.1/workplaceHomepage", "@type": "@id" }, "geo": "http://schema.org/geo", "latitude": { "@id": "http://schema.org/latitude", "@type": "xsd:float" }, "longitude": { "@id": "http://schema.org/longitude", "@type": "xsd:float" }, "xsd": "http://www.w3.org/2001/XMLSchema#" "Person": "http://xmlns.com/foaf/0.1/Person" }, "@id": "http://me.example.com", "@type": "Person", "name": "Jon Snow", "homepage": "http://jon-snow.winterfell/" "geo": { "latitude": "40.75", "longitude": "73.98" } }
What makes REST nice?• Stateless • No layer over HTTP • HTTPS made security trivial (and cheap) • One common format JSON • Not even a spec…
Be YourselfDon’t make it REST if it’s not
Hypermedia should be easy too
HAL
{ "id": 14196149, "name": "paw", "owner": { "login": "luckymarmot", "id": 3215332 ... } }
HAL{ "_links":{ "self": {"href":"/repos/luckymarmot/paw"}, "commits": {"href":"/repos/luckymarmot/paw/commits"} }, "id": 14196149, "name": "paw", "owner": { "_links":{ "self": {"href":"/users/luckymarmot"}, "followers": {"href":"/repos/luckymarmot/followers"} }, "login": "luckymarmot", "id": 3215332 ... } }
_url
{ "id": 14196149, "name": "paw", "owner": { "login": "luckymarmot", "id": 3215332, ... } }
_url{ "id": 14196149, "name": "paw", "url": "/repos/luckymarmot/paw", "commits_url":"/repos/luckymarmot/paw/commits" "owner": { "login": "luckymarmot", "id": 3215332, "url": "/users/luckymarmot", "followers_url": "/repos/luckymarmot/followers", ... } }
Demo
Make flexible apps?
{ "@context": { "name": "http://xmlns.com/foaf/0.1/name", "city": { "@id": "http://xmlns.com/foaf/0.1/workplaceHomepage", "@type": "@id" }, "Person": "http://xmlns.com/foaf/0.1/Person" }, "@id": "http://me.example.com", "@type": "Person", "name": "Jon Snow", "city": "http://city.winterfell/" }
Bring Hypermedia Further
{ "name": "Jon Snow", "partner": {
"status":"single" "url":null
} }
POST /person/jon.snow/partner
{ "name": "Jon Snow", "partner": {
"status":"married" "url":"/person/ygritte"
} }
"url":"/person/ygritte"
The Greeting Card Problem
{ "name": “Jon Snow", "partner": {
"status":"married" "url":"/person/ygritte", "congrats_url":"/greetings/…",
} }
"congrats_url":"/greetings/…",
• Headline • Message • Recipient(s) • Place of the wedding for marriage cards • Name of the baby for birth cards
POST /greetings
Links HAL, _url
Definition Swagger, RAML…
+
{ "name": "Jon Snow", "partner": {
"status":"married" "url":"/person/ygritte", "congrats":{ "url":"/greetings", "params":{ "message":{"in": "body", "required":true}, "weddingPlace":{"in": "body", "required":false} } }
} }
Content-Type: application/**+json
{ "name": "Jon Snow", "partner": {
"status":"married" "url":"/person/ygritte", "congrats":{ "url":"/greetings" }
} }
Content-Type: application/json
Know who you are
Make things people can (easily) use
Solve real problems• Adding links • GraphQL • Describing API possibilities
top related