1© 2013 by Intellectual Reserve, Inc. All rights reserved.
Hypermedia in Practice
2© 2013 by Intellectual Reserve, Inc. All rights reserved.
The Goal
3© 2013 by Intellectual Reserve, Inc. All rights reserved.
Learn how to use hypermedia for better Web service APIs.
The Goal
4© 2013 by Intellectual Reserve, Inc. All rights reserved.
Better?● More Adaptable● More Robust● More Maintainable● Less Pain
Learn how to use hypermedia for better Web service APIs.
The Goal
A Review
● Web service API– A set of digital services and/or resources
made accessible over a computer network.
● HTTP– Hypertext Transfer Protocol
– Defines how to make requests and interpret responses.
A Review
● Resources– The units of data making up the “matter” of
the API.
– The “subject” of HTTP operations.
● Uniform Resource Identifier– The locator for a resource.
– Includes a domain, path, query.
A Review
● Resource Representations– How resources are serialized to a stream of
bytes.
– Often JSON and XML.
– a.k.a. “media types” or “data formats”
● See “Architecture of the World Wide Web”– http://www.w3.org/TR/webarch/
Client
WWW
API Server
ResourceStore
URI
HTTP“GET /path/to/resource”
Resource
HTTP“GET /path/to/resource”
“OK"
ResourceRepresentation
<resource> …</resource>
{ “resource” : …}
These change.Frequently.
What If...
...a resource representationchanges its property order?
{ … “names” : [ … ], “facts” : [ … ], “gender” : { … }, …}
{ … “gender” : { … }, “names” : [ … ], “facts” : [ … ], …}
What If...
...a resource representationadds some whitespace?
{“names”:[ … ],“facts”:[ … ],“gender”:{ … },…}
{ “names” : [ … ], “facts” : [ … ], “gender” : { … }, …}
<person><name>...</name><fact>...</fact><gender>...</gender></person>
<person> <name>...</name> <fact>...</fact> <gender>...</gender></person>
What If...
...an XML representationchanges namespace prefixes?
<person xmlns=”...”> <name>...</name> <fact>...</fact> <gender>...</gender></person>
<gx:person xmlns:gx=”...”> <gx:name>...</gx:name> <gx:fact>...</gx:fact> <gx:gender>...</gx:gender></gx:person>
What If...
...a caching policy changes?What If...
...new resources become available?
Available Resources● Person● Relationship● Person Search● ...
Available Resources● Person● Relationship● Person Search● Records● Record● Record Search● ...
What If...
...an API changes domains?
https://familysearch.org/platform
https://familysearch.io/platform
What If...
...a resource moves?
/platform/tree/persons/12345/matches
/platform/tree/persons/12345/duplicates
What If...
...subresources are includedin their “parent” resource?
Person
/person/12345
PersonNotes
/person/12345/notes PersonSource
References
/person/12345/sources
Person+
Notes+
Source References
/person/12345
What If...
What If...● ...property order changes?● ...some whitespace is added?● ...XML changes namespace prefixes?● ...caching policy changes?● ...new resources are available?● ...a resource moves?● ...subresources are included in their
"parent" resource?
● ...property order changes?● ...some whitespace is added?● ...XML changes namespace prefixes?● ...caching policy changes?● ...new resources are available?● ...a resource moves?● ...subresources are included in their
"parent" resource?
What If...
Speaks HTTP fluently.
Understands the URI.
Uses links to get stuffdone.
...a resource representationchanges its property order?
<html> <head> … <script src=”...”></script> … </head> <body> … </body></html>
What If...
...a resource representationchanges its property order?
<html> <head> … <script src=”...”></script> … </head> <body> … </body></html>
What If...
<html> <head> … </head> <body> … <script src=”...”></script> … </body></html>
...a resource representationchanges its property order?
<html> <head> … <script src=”...”></script> … </head> <body> … </body></html>
What If...
<html> <head> … </head> <body> … <script src=”...”></script> … </body></html>
HTML says...
“OK”
...a resource representationchanges its property order?
{ … “names” : [ … ], “facts” : [ … ], “gender” : { … }, …}
{ … “gender” : { … }, “names” : [ … ], “facts” : [ … ], …}
What If...
...a resource representationchanges its property order?
{ … “names” : [ … ], “facts” : [ … ], “gender” : { … }, …}
{ … “gender” : { … }, “names” : [ … ], “facts” : [ … ], …}
What If...
GEDCOM X says...
“OK”
...a resource representationadds some whitespace?
What If...
<html><head>…</head><body>…</body></html>
...a resource representationadds some whitespace?
What If...
<html><head>…</head><body>…</body></html>
<html> <head> … </head> <body> … </body></html>
...a resource representationadds some whitespace?
What If...
<html><head>…</head><body>…</body></html>
<html> <head> … </head> <body> … </body></html>
HTML says...
“OK”
...a resource representationadds some whitespace?
{“names”:[ … ],“facts”:[ … ],“gender”:{ … },…}
{ “names” : [ … ], “facts” : [ … ], “gender” : { … }, …}
<person><name>...</name><fact>...</fact><gender>...</gender></person>
<person> <name>...</name> <fact>...</fact> <gender>...</gender></person>
What If...
...a resource representationadds some whitespace?
{ “names” : [ … ], “facts” : [ … ], “gender” : { … }, …}
<person><name>...</name><fact>...</fact><gender>...</gender></person>
<person> <name>...</name> <fact>...</fact> <gender>...</gender></person>
What If...
{“names”:[ … ],“facts”:[ … ],“gender”:{ … },…}
JSON says...
“OK”
...a resource representationadds some whitespace?
{ “names” : [ … ], “facts” : [ … ], “gender” : { … }, …}
<person><name>...</name><fact>...</fact><gender>...</gender></person>
<person> <name>...</name> <fact>...</fact> <gender>...</gender></person>
What If...
{“names”:[ … ],“facts”:[ … ],“gender”:{ … },…}
XML says...
“OK”
...an XML representationchanges namespace prefixes?
<person xmlns=”...”> <name>...</name> <fact>...</fact> <gender>...</gender></person>
<gx:person xmlns:gx=”...”> <gx:name>...</gx:name> <gx:fact>...</gx:fact> <gx:gender>...</gx:gender></gx:person>
What If...
...an XML representationchanges namespace prefixes?
<person xmlns=”...”> <name>...</name> <fact>...</fact> <gender>...</gender></person>
<gx:person xmlns:gx=”...”> <gx:name>...</gx:name> <gx:fact>...</gx:fact> <gx:gender>...</gx:gender></gx:person>
What If...XML says...
“OK”
...a caching policy changes?What If...
HTTP/1.1 200 OK…Cache-Control: no-store…
HTTP/1.1 200 OK…Cache-Control: no-store…
...a caching policy changes?What If...
HTTP/1.1 200 OK…Cache-Control: no-store…
HTTP/1.1 200 OK…Cache-Control: no-store…
HTTP/1.1 200 OK…Cache-Control: public, max-age=3600ETag: 1234567890…
...a caching policy changes?What If...
HTTP/1.1 200 OK…Cache-Control: no-store…
HTTP/1.1 200 OK…Cache-Control: no-store…
HTTP/1.1 200 OK…Cache-Control: public, max-age=3600ETag: 1234567890…
HTTP says...
“OK”
...a caching policy changes?What If...
...new resources become available?What If...
...new resources become available?What If...
...new resources become available?
Available Resources● Person● Relationship● Person Search● ...
Available Resources● Person● Relationship● Person Search● Records● Record● Record Search● ...
What If...
...new resources become available?
Available Resources● Person● Relationship● Person Search● ...
Available Resources● Person● Relationship● Person Search● Records● Record● Record Search● ...
What If...
Hypermedia
...an API changes domains?What If...
...an API changes domains?What If...
HTTP/1.1 301 Moved Permanently…Location: http://www.facebook.com/…
HTTP says...
“Moved”
...an API changes domains?What If...
...an API changes domains?What If...
HTTP/1.1 301 Moved Permanently…Location: http://familysearch.io/…
...a resource moves?
/platform/tree/persons/12345/matches
/platform/tree/persons/12345/duplicates
What If...
...a resource moves?What If...
<html> <body> … <form action=”/path/to/resource”> <input …/> </form> </body></html>
...a resource moves?What If...
<html> <body> … <form action=”/path/to/resource”> <input …/> </form> </body></html>
<html> <body> … <form action=”/NEW/resource/PATH”> <input …/> </form> </body></html>
...a resource moves?What If...
<html> <body> … <form action=”/path/to/resource”> <input …/> </form> </body></html>
<html> <body> … <form action=”/NEW/resource/PATH”> <input …/> </form> </body></html>
Hypermedia
...a resource moves?What If...
<gedcomx> <person id=”12345”> … <link rel=”matches” href=”/persons/12345/matches”/> … </person></gedcomx>
...a resource moves?What If...
<gedcomx> <person id=”12345”> … <link rel=”matches” href=”/persons/12345/matches”/> … </person></gedcomx>
<gedcomx> <person id=”12345”> … <link rel=”matches” href=”/persons/12345/duplicates”/> … </person></gedcomx>
...a resource moves?What If...
<gedcomx> <person id=”12345”> … <link rel=”matches” href=”/persons/12345/matches”/> … </person></gedcomx>
<gedcomx> <person id=”12345”> … <link rel=”matches” href=”/persons/12345/duplicates”/> … </person></gedcomx>
Hypermedia
...subresources are includedin their “parent” resource?
Person
/person/12345
PersonNotes
/person/12345/notes PersonSource
References
/person/12345/sources
Person+
Notes+
Source References
/person/12345
What If...
...subresources are includedin their “parent” resource?
What If...
<html> <head> … <link rel=”stylesheet” href=”...”/> <script src=”...”></script> … </head> <body> … </body></html>
...subresources are includedin their “parent” resource?
What If...
<html> <head> … <link rel=”stylesheet” href=”...”/> <script src=”...”></script> … </head> <body> … </body></html>
Embedded Links(Hypermedia)
...subresources are includedin their “parent” resource?
What If...
<html> <head> … <link rel=”stylesheet” href=”...”/> <script src=”...”></script> … </head> <body> … </body></html>
<html> <head> … <style> … </style> <script> … </script> … </head> <body> … </body></html>
...subresources are includedin their “parent” resource?
What If...
<html> <head> … <link rel=”stylesheet” href=”...”/> <script src=”...”></script> … </head> <body> … </body></html>
<html> <head> … <style> … </style> <script> … </script> … </head> <body> … </body></html>
HTML says...
“OK”
...subresources are includedin their “parent” resource?
What If...
<gedcomx> <person id=”12345”> … <link rel=”source-references” href=”/persons/12345/sources”/> <link rel=”notes” href=”/persons/12345/notes”/> … </person></gedcomx>
...subresources are includedin their “parent” resource?
What If...
<gedcomx> <person id=”12345”> … <link rel=”source-references” href=”/persons/12345/sources”/> <link rel=”notes” href=”/persons/12345/notes”/> … </person></gedcomx>
Embedded Links(Hypermedia)
...subresources are includedin their “parent” resource?
What If...
<gedcomx> <person id=”12345”> … <link rel=”source-references” href=”/persons/12345/sources”/> <link rel=”notes” href=”/persons/12345/notes”/> … </person></gedcomx>
<gedcomx> <person id=”12345”> … <source description=”...”/> <note id=”...”> … </note> </person></gedcomx>
...subresources are includedin their “parent” resource?
What If...
<gedcomx> <person id=”12345”> … <link rel=”source-references” href=”/persons/12345/sources”/> <link rel=”notes” href=”/persons/12345/notes”/> … </person></gedcomx>
<gedcomx> <person id=”12345”> … <source description=”...”/> <note id=”...”> … </note> </person></gedcomx>
GEDCOM X says...
“OK”
So.
So.● Speak HTTP fluently.● Understand the URI.● Use links to get stuff done.
So.
Yeah. Like a screen scraper.
● Speak HTTP fluently.● Understand the URI.● Use links to get stuff done.
links
linksWhat do
look like?
linksWhat do
look like?Depends on the media type.
links
<a href=”...”/>
<link rel=”” href=””/>
<img src=”...”/>
<script src=”...”/>
linksWhy use
?So APIs can changewithout breaking clients.
How To...
How To...● Add a person to a collection.● Search a collection for persons.● Do a “full” person read.● Upload an artifact to a collection.● Edit the birth date of a person.● Read the list of photos on a person.● Delete a person.
How To...Add a person to a collection.
● Read the collection.● Find the link to the “persons” of the
collection.● POST the new person to that URI.
How To...Add a person to a collection.
● Read the collection.● Find the link to the “persons” of the
collection.● POST the new person to that URI.
How To...Add a person to a collection.
GET /platform/collections/tree
<gedcomx xmlns=”http://gedcomx.org/v1”>
<collection> <title>FamilySearch Family Tree</title> ... <link rel=”persons” href=”/path/to/persons/resource”/> ... </collection>
</gedcomx>
How To...Search a collection for persons.
● Read the collection.● Find the link to the “person-search” of the
collection.● Fill in the parameters and issue the
request.
How To...
GET /platform/collections/tree
<gedcomx xmlns=”http://gedcomx.org/v1”>
<collection> <title>FamilySearch Family Tree</title> ... <link rel=”person-search” template=”/path/to/person/search{?q}”/> ... </collection>
</gedcomx>
Search a collection for persons.
How To...Do a “full” person read.
● Read the person.● For each “embedded” link, get the
resource and embed it.– Source references
– Discussion references
– Notes
– Relationships
How To...Do a “full” person read.
<gedcomx xmlns=”http://gedcomx.org/v1”>
<person id=”P2”> <name>...</name> ... <link rel=”source-references” href=”/path/to/refs”/> <link rel=”notes” href=”/path/to/notes”/> <link rel=”child-relationships” href=”/path/to/rels”/> <link rel=”parent-relationships” href=”/path/to/rels”/> <link rel=”spouse-relationships” href=”/path/to/rels”/> ... </person>
</gedcomx>
How To...Upload an artifact to a collection.
● Read the collection.● Find the link to the “artifacts”.● POST the artifact.
How To...Upload an artifact to a collection.
GET /platform/collections/tree
<gedcomx xmlns=”http://gedcomx.org/v1”>
<collection> <title>FamilySearch Family Tree</title> ... <link rel=”artifacts” href=”/path/to/artifacts/resource”/> ... </collection>
</gedcomx>
How To...Edit the birth date of a person.
● Read the person.● Find the link to the “conclusions” of the
person.● POST the changes.
How To...Edit the birth date of a person.
<gedcomx xmlns=”http://gedcomx.org/v1”>
<person id=”P2”> <name>...</name> ... <link rel=”conclusions” href=”/path/to/conclusions”/> ... </person>
</gedcomx>
How To...Read the list of photos on a person.
● Read the person.● Find the link to the “artifacts” of the
person.
How To...Read the list of photos on a person.
<gedcomx xmlns=”http://gedcomx.org/v1”>
<person id=”P2”> <name>...</name> ... <link rel=”artifacts” href=”/path/to/artifacts”/> ... </person>
</gedcomx>
How To...Delete a person.
● Read the person.● Find the “self” link.● Apply the DELETE.
How To...Delete a person.
<gedcomx xmlns=”http://gedcomx.org/v1”>
<person id=”P2”> <name>...</name> ... <link rel=”person” href=”/path/to/self”/> ... </person>
</gedcomx>
97© 2013 by Intellectual Reserve, Inc. All rights reserved.
Tools
98© 2013 by Intellectual Reserve, Inc. All rights reserved.
Do I have to?
99© 2013 by Intellectual Reserve, Inc. All rights reserved.
The Goal
100© 2013 by Intellectual Reserve, Inc. All rights reserved.
Better?● More Adaptable● More Robust● More Maintainable● Less Pain
Learn how to use hypermedia for better Web service APIs.
The Goal