Skip to content

Instantly share code, notes, and snippets.

@soofaloofa
Forked from soofaloofa-zz/ On choosing a hypermedia type
Last active October 20, 2023 19:21
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save soofaloofa/bc3f82793baa79dd897a7d2588841a07 to your computer and use it in GitHub Desktop.
Save soofaloofa/bc3f82793baa79dd897a7d2588841a07 to your computer and use it in GitHub Desktop.
On choosing a hypermedia type for your API - HAL, JSON-LD, Collection+JSON, SIREN, Oh My!
GET https://api.example.com/player/1234567890
{
"collection": {
"version": "1.0",
"href": "https://api.example.com/player",
"items": [
{
"href": "https://api.example.com/player/1234567890",
"data": [
{"name": "playerId", "value": "1234567890", "prompt": "Identifier"},
{"name": "name", "value": "Kevin Sookocheff", "prompt": "Full Name"},
{"name": "alternateName", "value": "soofaloofa", "prompt": "Alias"}
],
"links": [
{"rel": "image", "href": "https://api.example.com/player/1234567890/avatar.png", "prompt": "Avatar", "render": "image" },
{"rel": "friends", "href": "https://api.example.com/player/1234567890/friends", "prompt": "Friends" }
]
}
]
}
}
GET https://api.example.com/player/1234567890/friends
{
"collection":
{
"version": "1.0",
"href": "https://api.example.com/player/1234567890/friends",
"links": [
{"rel": "next", "href": "https://api.example.com/player/1234567890/friends?page=2"}
],
"items": [
{
"href": "https://api.example.com/player/1895638109",
"data": [
{"name": "playerId", "value": "1895638109", "prompt": "Identifier"},
{"name": "name", "value": "Sheldon Dong", "prompt": "Full Name"},
{"name": "alternateName", "value": "sdong", "prompt": "Alias"}
],
"links": [
{"rel": "image", "href": "https://api.example.com/player/1895638109/avatar.png", "prompt": "Avatar", "render": "image" },
{"rel": "friends", "href": "https://api.example.com/player/1895638109/friends", "prompt": "Friends" }
]
},
{
"href": "https://api.example.com/player/8371023509",
"data": [
{"name": "playerId", "value": "8371023509", "prompt": "Identifier"},
{"name": "name", "value": "Martin Liu", "prompt": "Full Name"},
{"name": "alternateName", "value": "mliu", "prompt": "Alias"}
],
"links": [
{"rel": "image", "href": "https://api.example.com/player/8371023509/avatar.png", "prompt": "Avatar", "render": "image" },
{"rel": "friends", "href": "https://api.example.com/player/8371023509/friends", "prompt": "Friends" }
]
}
],
"queries": [
{
"rel": "search", "href": "https://api.example.com/player/1234567890/friends/search", "prompt": "Search",
"data": [
{"name": "search", "value": ""}
]
}
],
"template": {
"data": [
{"name": "playerId", "value": "", "prompt": "Identifier" },
{"name": "name", "value": "", "prompt": "Full Name"},
{"name": "alternateName", "value": "", "prompt": "Alias"},
{"name": "image", "value": "", "prompt": "Avatar"}
]
}
}
}
GET https://api.example.com/player/1234567890
{
"_links": {
"self": { "href": "https://api.example.com/player/1234567890" },
"curies": [{ "name": "ex", "href": "https://api.example.com/docs/rels/{rel}", "templated": true }],
"ex:friends": { "href": "https://api.example.com/player/1234567890/friends" }
},
"playerId": "1234567890",
"name": "Kevin Sookocheff",
"alternateName": "soofaloofa",
"image": "https://api.example.com/player/1234567890/avatar.png"
}
GET https://api.example.com/player/1234567890/friends
{
"_links": {
"self": { "href": "https://api.example.com/player/1234567890/friends" },
"next": { "href": "https://api.example.com/player/1234567890/friends?page=2" }
},
"size": "2",
"_embedded": {
"player": [
{
"_links": {
"self": { "href": "https://api.example.com/player/1895638109" },
"friends": { "href": "https://api.example.com/player/1895638109/friends" }
},
"playerId": "1895638109",
"name": "Sheldon Dong",
"alternateName": "sdong",
"image": "https://api.example.com/player/1895638109/avatar.png"
},
{
"_links": {
"self": { "href": "https://api.example.com/player/8371023509" },
"friends": { "href": "https://api.example.com/player/8371023509/friends" }
},
"playerId": "8371023509",
"name": "Martin Liu",
"alternateName": "mliu",
"image": "https://api.example.com/player/8371023509/avatar.png"
}
]
}
}
GET https://api.example.com/player/1234567890
{
"@context": {
"@vocab": "https://schema.org/",
"image": { "@type": "@id" },
"friends": { "@type": "@id" }
},
"@id": "https://api.example.com/player/1234567890",
"playerId": "1234567890",
"name": "Kevin Sookocheff",
"alternateName": "soofaloofa",
"image": "https://api.example.com/player/1234567890/avatar.png",
"friends": "https://api.example.com/player/1234567890/friends"
}
GET https://api.example.com/player/1234567890/friends
{
"@context": [
"http://www.w3.org/ns/hydra/core",
{
"@vocab": "https://schema.org/",
"image": { "@type": "@id" },
"friends": { "@type": "@id" }
}
],
"@id": "https://api.example.com/player/1234567890/friends",
"operation": {
"@type": "BefriendAction",
"method": "POST",
"expects": {
"@id": "http://schema.org/Person",
"supportedProperty": [
{ "property": "name", "range": "Text" },
{ "property": "alternateName", "range": "Text" },
{ "property": "image", "range": "URL" }
]
}
},
"member": [
{
"@id": "https://api.example.com/player/1895638109",
"name": "Sheldon Dong",
"alternateName": "sdong",
"image": "https://api.example.com/player/1895638109/avatar.png",
"friends": "https://api.example.com/player/1895638109/friends"
},
{
"@id": "https://api.example.com/player/8371023509",
"name": "Martin Liu",
"alternateName": "mliu",
"image": "https://api.example.com/player/8371023509/avatar.png",
"friends": "https://api.example.com/player/8371023509/friends"
}
],
"nextPage": "https://api.example.com/player/1234567890/friends?page=2"
}
{
"data": {
"type": "players",
"id": "1234567890",
"attributes": {
"name": "Kevin Sookocheff",
"alternateName": "soofaloofa",
"image": "https://api.example.com/player/1234567890/avatar.png"
},
"relationships": {
"friends": {
"data": [
{ "type": "players", "id": "1895638109" },
{ "type": "players", "id": "8371023509" }
],
"links": {
"self": "https://api.example.com/player/1234567890/friends/",
"next": "https://api.example.com/player/1234567890/friends?page=2"
}
}
}
},
"links": {
"self": "https://api.example.com/player/1234567890/",
"friends": "https://api.example.com/player/1234567890/friends/"
},
"included": [
{
"type": "players",
"id": "1895638109",
"attributes": {
"alternateName": "sdong",
"name": "Sheldon Dong",
"image": "https://api.example.com/player/1895638109/avatar.png"
}
},
{
"type": "players",
"id": "8371023509",
"attributes": {
"alternateName": "mliu",
"name": "Martin Liu",
"image": "https://api.example.com/player/8371023509/avatar.png"
}
}
]
}
A comparison of Collection+JSON, HAL, JSON-LD and SIREN media types.
Discussion at
http://sookocheff.com/posts/2014-03-11-on-choosing-a-hypermedia-format/
GET https://api.example.com/player/1234567890
{
"class": "player",
"links": [
{ "rel": [ "self" ], "href": "https://api.example.com/player/1234567890" },
{ "rel": [ "friends" ], "href": "https://api.example.com/player/1234567890/friends" }
],
"properties": {
"playerId": "1234567890",
"name": "Kevin Sookocheff",
"alternateName": "soofaloofa",
"image": "https://api.example.com/player/1234567890/avatar.png"
}
}
GET https://api.example.com/player/1234567890/friends
{
"class": "player",
"links": [
{"rel": [ "self" ], "href": "https://api.example.com/player/1234567890/friends"},
{"rel": [ "next" ], "href": "https://api.example.com/player/1234567890/friends?page=2"}
],
"actions": [{
"class": "add-friend",
"href": "https://api.example.com/player/1234567890/friends",
"method": "POST",
"fields": [
{"name": "name", "type": "string"},
{"name": "alternateName", "type": "string"},
{"name": "image", "type": "href"}
]
}],
"properties": {
"size": "2"
},
"entities": [
{
"links": [
{"rel": [ "self" ], "href": "https://api.example.com/player/1895638109"},
{"rel": [ "friends" ], "href": "https://api.example.com/player/1895638109/friends"}
],
"properties": {
"playerId": "1895638109",
"name": "Sheldon Dong",
"alternateName": "sdong",
"image": "https://api.example.com/player/1895638109/avatar.png"
}
},
{
"links": [
{"rel": [ "self" ], "href": "https://api.example.com/player/8371023509"},
{"rel": [ "friends" ], "href": "https://api.example.com/player/8371023509/friends" }
],
"properties": {
"playerId": "8371023509",
"name": "Martin Liu",
"alternateName": "mliu",
"image": "https://api.example.com/player/8371023509/avatar.png"
}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment