The never-ending REST
API design debate
Guillaume Laforge
Restlet — the Web API platform
Chair of the Apache Groovy PMC
@glaforge
We know
about
APIs!
http://restlet.com
We know
about
APIs!
http://restlet.com
ROY FIELDING
RESTDISSERTATION
ROY FIELDING
RESTDISSERTATION
Principled design
of the modern
Web architecture
4
Representational State Transfer
Architectural properties
• Performance
• Scalability
• Simplicity
• Modifiability
• Visibility
• Portability
• Reliability
Architectural constraints
• Client-server
• Stateless
• Cacheable
• Layered system
• Code on demand (optional)
• Uniform interface
5
REST — Uniform interface
• Identification of resources
• Manipulation of resources 

through representations
• Self-descriptive messages
• HATEOAS 

(Hypermedia AsThe Engine 

Of Application State)
5
REST — Uniform interface
• Identification of resources
• Manipulation of resources 

through representations
• Self-descriptive messages
• HATEOAS 

(Hypermedia AsThe Engine 

Of Application State)
Resource as URIs
http://api.co/cars/123
5
REST — Uniform interface
• Identification of resources
• Manipulation of resources 

through representations
• Self-descriptive messages
• HATEOAS 

(Hypermedia AsThe Engine 

Of Application State)
Resource as URIs
http://api.co/cars/123
JSON, XML…
5
REST — Uniform interface
• Identification of resources
• Manipulation of resources 

through representations
• Self-descriptive messages
• HATEOAS 

(Hypermedia AsThe Engine 

Of Application State)
Resource as URIs
http://api.co/cars/123
JSON, XML…
HTTP GET, POST, PUT, DELETE
media types, cacheability…
5
REST — Uniform interface
• Identification of resources
• Manipulation of resources 

through representations
• Self-descriptive messages
• HATEOAS 

(Hypermedia AsThe Engine 

Of Application State)
Resource as URIs
http://api.co/cars/123
JSON, XML…
HTTP GET, POST, PUT, DELETE
media types, cacheability…
Hypermedia APIs
HAL, JSON-LD, Siren…
6
HTTP methods / URIs for collection/item
GET
POST
PUT
DELETE
http://api.co/v2/cars/ http://api.co/v2/cars/1234
List all the cars Retrieve an individual car
Create a new car Error
Replace the entire collection
with a whole new list of cars
Replace or create
an individual car
Delete all the cars Delete an individual car
NOUNS
ARE GOOD
VERBS
ARE BAD
8
Nouns are good, verbs are bad!
• Prefer nouns to verbs
• nouns refer to resources
• resources are handled with HTTP verbs
• Verbs can be used for actions or calculations
• /login, /logout
• /convertTemperature
• /repositories/123/star
10
Singular or plural resources?
• Prefer plural forms
• /tickets/234 vs /ticket/234
• Avoid confusing odd singular vs plural forms
• /person vs /people, or /goose vs /geese
• Easier for URL routing (same prefix)
• Think of it as: 

‘This is the 234th item of the tickets collection’
Camel
case?
Camel
case?
Snake
case!
12
Different casing in the wild
• UpperCamelCase or lowerCamelCase
• snake_case or dashed-snake-case
• Prefer lowercase
• Prefer snake_case
• Underscores seem more common in APIs
• But chose one casing and be consistent!
13
Dealing with relations in your URLs
• /tickets/123/messages/4
• a ticket could be a group of messages
• /usergroups/234/users/67
• a user could belong to different usergroups
• user should have a URL of its own, referenced from the
usergroup payload
API PARAMETERS
RULE OF THUMBS
15
API parameters — rule of thumbs
• Path
• required, resource identifier
• Query
• optional, query collections
• Body
• resource specific logic
• Header
• global, platform-wide
16
HTTP Status Code Map http://bit.ly/stcode
17
Common HTTP status codes
• Use appropriate HTTP status codes when answering
requests:
• 1xx: Hold on…
• 2xx: Here you go!
• 3xx: Go away!
• 4xx:You fucked up :-D
• 5xx: I fucked up :-(
18
Common HTTP Status Codes — 1xx
19
Common HTTP Status Codes — 2xx
19
Common HTTP Status Codes — 2xx
19
Common HTTP Status Codes — 2xx
19
Common HTTP Status Codes — 2xx
19
Common HTTP Status Codes — 2xx
19
Common HTTP Status Codes — 2xx
NOT
JUST
200
201
202
204
206
Anti-pattern:
returns 200
for everything,
even errors!
22
Not just 200 OK! — 201 Created
• Specify a Location header, pointing at the location of the
newly created resource
POST /cars ...
HTTP/1.1 201 Created
Location: http://cars.co/v2/cars/5959
API navigation is
important to make the
API more discoverable
24
DHC by Restlet: API testing tool
25
Not just 200 OK! — 202 Accepted
• Request accepted but will be handled asynchronously
• a job might be running later and yield a result later on
POST /jobs ...
HTTP/1.1 202 Accepted
No payload
returned
26
Not just 200 OK! — 204 No content
• The resource was deleted and no payload is returned
• but could return 200 OK 

& provide the payload of the deleted element
DELETE /tickets/654
HTTP/1.1 204 No content
27
Not just 200 OK! — 206 Partial content
• A partial list of meteorites is returned, using pagination
• add a Link header to facilitate navigation
GET /meteorites?page=4
HTTP/1.1 206 Partial content
Link: <http://nasa.co/meteorites?page=1>; rel="first", 

<http://nasa.co/meteorites?page=3>; rel="prev",
<http://nasa.co/meteorites?page=5>; rel="next", 

<http://nasa.co/meteorites?page=9>; rel="last"
...
28
Not just 200 OK! — 304 Not modified
• When HTTP caching headers are in play
• the client should have a version in cache already
GET /meteorites/654
HTTP/1.1 304 Not modified
Caching!
30
Last-Modified
GET /users/123
Modified-Since: Fri, 13 Nov 2015 02:13:11 GMT
HTTP/1.1 200 OK
Last-Modified: Sun, 15 Nov 2015 04:58:08 GMT
31
ETag
GET /users/123
If-None-Match: a456ef544eeb7333af
HTTP/1.1 200 OK
ETag: 686897696a7c876b7e
GET /users/123
If-None-Match: 686897696a7c876b7e
HTTP/1.1 304 Not modified
PAGINATION
33
Pagination with query parameters
• With a page number: ?page=23
• can also specify a page size
• might get odd results when insertions happen
• With a cursor: ?cursor=34ea3fd6
• insertion-friendly
• With a semantic parameter: ?page=A
• interesting when limited / discrete number of pages
34
Pagination with accept range header
• Accept range header not just for bytes
GET /users
HTTP/1.1 206 Partial content
Accept-Ranges: users
Content-Range: users 0-9/200
GET /users
Range: users=0-9
Wrapped
CollectionS
36
Wrapped collections
• Prefer unwrapped collections
• unless there’s specific collection payload metadata

(example: photo album details)
• pagination are better in HTTP headers
GET /tickets
Content-Type: application/json
{
data: [
{ id: 1, ... },
{ id: 2, ... }
]
}
GET /tickets
Content-Type: application/json
[
{ id: 1, ... },
{ id: 2, ... }
]
37
Common HTTP Status Codes — 3xx
37
Common HTTP Status Codes — 3xx
37
Common HTTP Status Codes — 3xx
37
Common HTTP Status Codes — 3xx
37
Common HTTP Status Codes — 3xx
37
Common HTTP Status Codes — 3xx
38
Common HTTP Status Codes — 4xx
38
Common HTTP Status Codes — 4xx
38
Common HTTP Status Codes — 4xx
38
Common HTTP Status Codes — 4xx
38
Common HTTP Status Codes — 4xx
38
Common HTTP Status Codes — 4xx
39
Provide helpful error payloads
• No definitive standard yet
• http problem proposal and vnd-error mime type
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
Content-Language: en
{
"type": "https://example.com/probs/out-of-credit",
"title": "You do not have enough credit.",
"detail": "Your current balance is 30, but that costs 50.",
"instance": "/account/12345/msgs/abc",
"balance": 30,
"accounts": ["/account/12345", "/account/67890"]
}
40
Common HTTP Status Codes — 5xx
40
Common HTTP Status Codes — 5xx
40
Common HTTP Status Codes — 5xx
40
Common HTTP Status Codes — 5xx
41
Treating unknown status codes
• An unknown status code should be treated 

as the first one of the family
• 4xx — 400 generic client error
• 5xx — 500 generic server error
RATE
LIMITATION
43
Rate limitation
HTTP/1.1 200 OK
Date: Mon, 01 Jul 2013 17:27:06 GMT
Status: 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 56
X-RateLimit-Reset: 1372700873
Total number of
requests allowed
Number of
requests left
remaining window before
the rate limit resets in UTC
epoch seconds
ONE
SIZE
FITS
ALL
Different payloads
for different
consumers
45
Selecting with query parameters
• Only 5 stars Chinese restaurants
• GET https://api.co/restaurants?type=chinese&stars=5
FILTERING
47
Filtering
• Specify fields you’re interested in:
• GET https://api.co/users/123?fields=firstname,lastname,age
• Specify excluded fields:
• GET https://api.co/users/123?exclude=biography,resume
• Specify a « style »:
• GET https://api.co/users/123?style=compact
48
Prefer… the prefer header
GET /users/123 HTTP/1.1
Content-Type: application/json
Prefer: return=minimal
Vary: Prefer,Accept,Accept-Encoding
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Vary: Prefer,Accept,Accept-Encoding
Preference-Applied: return=minimal
Define different
profiles: minimal,
mobile, full…
49
Expanding referenced resources
• Use the dot notation to explicit you want sub-resources
• GET https://api.co/users/123?fields=address.zip
• user
• name
• address
• zip
• country
• …
• …
SORTING
51
Sorting
• SQL-style
• GET https://api.co/books?sort=title+DESC
• GET https://api.co/books?sort=title+DESC,author+ASC
• Sort + asc/desc combo
• GET https://api.co/books?sort=title&desc=title
• GET https://api.co/books?
sort=title,author&desc=title&asc=author
SEARCHING
53
Searching
• Combien various filtering fields
• Or provide a full-blown query language
v1
55
Different approaches for API versioning
• Most frequent, in the URL:
• https://api.com/v2/restaurants/1234
• Custom header:
• X-API-Version: 2
• Less frequent, with an accept header
• clients don’t have to change endpoint, but update headers
GET /restaurants
Accept: application/vnd.restaurants.v2+json
hypermedia
57
Richardson maturity model
58
Pros & Cons of hypermedia
• Pros
• more generic clients
• can palliate the need for API versioning
• Cons
• heavier payload (think mobile devices w/ bad connectivity)
• clients still need to understand what links are about and
how to represent them in their UI
C
H
A
N
G
E
IS
U
N
A
V
O
ID
A
B
L
E
60
Lots of choice
• HAL
• JSON-LD
• Collection+JSON
• SIREN
• …
• Which to chose from?
• no real consensus yet
• but HAL seems quite common
61
A word about IDs for linked resources
• If you’re tempted to go your own way for hypermedia…
• Be sure to define direct links to resources
• photos: [http://news.co/articles/123/photos/654,

http://news.co/articles/123/photos/659]
• Not mere IDs for which API clients need to figure out the
exact resource location (error-prone)
• photos: [654, 659]
62
Another word about IDs
• Usually avoid counter-type IDs: 1, 2, 3, 4…
• Prefer UUIDs
• makes it harder for malignant users 

to scan & discover existing resources
• auto-incrementing IDs might not be unique 

in distributed systems
HAL
I’m sorry Dave, I
can do Hypermedia
64
HAL approach
GET https://api.com/player/1234567890
HTTP/1.1 200 OK
{
"_links": {
"self": { "href": "https://api.com/player/1234567890" },
"friends": { "href": "https://api.com/player/1234567890/friends" }
},
"playerId": "1234567890",
"name": "Kevin Sookocheff",
"alternateName": "soofaloofa",
"image": "https://api.com/player/1234567890/avatar.png"
}
Special _links property
Resources
66
API design resources
• http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
• https://github.com/paypal/api-standards/blob/master/api-style-guide.md
• http://blog.octo.com/en/design-a-rest-api/
• https://github.com/interagent/http-api-design/blob/master/SUMMARY.md
• http://sookocheff.com/post/api/on-choosing-a-hypermedia-format/
• http://www.troyhunt.com/2014/02/your-api-versioning-is-wrong-which-is.html
Thanks for your attention
Questions & Answers

The never-ending REST API design debate

  • 1.
    The never-ending REST APIdesign debate Guillaume Laforge Restlet — the Web API platform Chair of the Apache Groovy PMC @glaforge
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
    4 Representational State Transfer Architecturalproperties • Performance • Scalability • Simplicity • Modifiability • Visibility • Portability • Reliability Architectural constraints • Client-server • Stateless • Cacheable • Layered system • Code on demand (optional) • Uniform interface
  • 7.
    5 REST — Uniforminterface • Identification of resources • Manipulation of resources 
 through representations • Self-descriptive messages • HATEOAS 
 (Hypermedia AsThe Engine 
 Of Application State)
  • 8.
    5 REST — Uniforminterface • Identification of resources • Manipulation of resources 
 through representations • Self-descriptive messages • HATEOAS 
 (Hypermedia AsThe Engine 
 Of Application State) Resource as URIs http://api.co/cars/123
  • 9.
    5 REST — Uniforminterface • Identification of resources • Manipulation of resources 
 through representations • Self-descriptive messages • HATEOAS 
 (Hypermedia AsThe Engine 
 Of Application State) Resource as URIs http://api.co/cars/123 JSON, XML…
  • 10.
    5 REST — Uniforminterface • Identification of resources • Manipulation of resources 
 through representations • Self-descriptive messages • HATEOAS 
 (Hypermedia AsThe Engine 
 Of Application State) Resource as URIs http://api.co/cars/123 JSON, XML… HTTP GET, POST, PUT, DELETE media types, cacheability…
  • 11.
    5 REST — Uniforminterface • Identification of resources • Manipulation of resources 
 through representations • Self-descriptive messages • HATEOAS 
 (Hypermedia AsThe Engine 
 Of Application State) Resource as URIs http://api.co/cars/123 JSON, XML… HTTP GET, POST, PUT, DELETE media types, cacheability… Hypermedia APIs HAL, JSON-LD, Siren…
  • 12.
    6 HTTP methods /URIs for collection/item GET POST PUT DELETE http://api.co/v2/cars/ http://api.co/v2/cars/1234 List all the cars Retrieve an individual car Create a new car Error Replace the entire collection with a whole new list of cars Replace or create an individual car Delete all the cars Delete an individual car
  • 13.
  • 14.
    8 Nouns are good,verbs are bad! • Prefer nouns to verbs • nouns refer to resources • resources are handled with HTTP verbs • Verbs can be used for actions or calculations • /login, /logout • /convertTemperature • /repositories/123/star
  • 16.
    10 Singular or pluralresources? • Prefer plural forms • /tickets/234 vs /ticket/234 • Avoid confusing odd singular vs plural forms • /person vs /people, or /goose vs /geese • Easier for URL routing (same prefix) • Think of it as: 
 ‘This is the 234th item of the tickets collection’
  • 17.
  • 18.
  • 19.
    12 Different casing inthe wild • UpperCamelCase or lowerCamelCase • snake_case or dashed-snake-case • Prefer lowercase • Prefer snake_case • Underscores seem more common in APIs • But chose one casing and be consistent!
  • 20.
    13 Dealing with relationsin your URLs • /tickets/123/messages/4 • a ticket could be a group of messages • /usergroups/234/users/67 • a user could belong to different usergroups • user should have a URL of its own, referenced from the usergroup payload
  • 21.
  • 22.
    15 API parameters —rule of thumbs • Path • required, resource identifier • Query • optional, query collections • Body • resource specific logic • Header • global, platform-wide
  • 23.
    16 HTTP Status CodeMap http://bit.ly/stcode
  • 24.
    17 Common HTTP statuscodes • Use appropriate HTTP status codes when answering requests: • 1xx: Hold on… • 2xx: Here you go! • 3xx: Go away! • 4xx:You fucked up :-D • 5xx: I fucked up :-(
  • 25.
    18 Common HTTP StatusCodes — 1xx
  • 26.
    19 Common HTTP StatusCodes — 2xx
  • 27.
    19 Common HTTP StatusCodes — 2xx
  • 28.
    19 Common HTTP StatusCodes — 2xx
  • 29.
    19 Common HTTP StatusCodes — 2xx
  • 30.
    19 Common HTTP StatusCodes — 2xx
  • 31.
    19 Common HTTP StatusCodes — 2xx
  • 32.
  • 33.
  • 34.
    22 Not just 200OK! — 201 Created • Specify a Location header, pointing at the location of the newly created resource POST /cars ... HTTP/1.1 201 Created Location: http://cars.co/v2/cars/5959
  • 35.
    API navigation is importantto make the API more discoverable
  • 36.
    24 DHC by Restlet:API testing tool
  • 37.
    25 Not just 200OK! — 202 Accepted • Request accepted but will be handled asynchronously • a job might be running later and yield a result later on POST /jobs ... HTTP/1.1 202 Accepted No payload returned
  • 38.
    26 Not just 200OK! — 204 No content • The resource was deleted and no payload is returned • but could return 200 OK 
 & provide the payload of the deleted element DELETE /tickets/654 HTTP/1.1 204 No content
  • 39.
    27 Not just 200OK! — 206 Partial content • A partial list of meteorites is returned, using pagination • add a Link header to facilitate navigation GET /meteorites?page=4 HTTP/1.1 206 Partial content Link: <http://nasa.co/meteorites?page=1>; rel="first", 
 <http://nasa.co/meteorites?page=3>; rel="prev", <http://nasa.co/meteorites?page=5>; rel="next", 
 <http://nasa.co/meteorites?page=9>; rel="last" ...
  • 40.
    28 Not just 200OK! — 304 Not modified • When HTTP caching headers are in play • the client should have a version in cache already GET /meteorites/654 HTTP/1.1 304 Not modified
  • 41.
  • 42.
    30 Last-Modified GET /users/123 Modified-Since: Fri,13 Nov 2015 02:13:11 GMT HTTP/1.1 200 OK Last-Modified: Sun, 15 Nov 2015 04:58:08 GMT
  • 43.
    31 ETag GET /users/123 If-None-Match: a456ef544eeb7333af HTTP/1.1200 OK ETag: 686897696a7c876b7e GET /users/123 If-None-Match: 686897696a7c876b7e HTTP/1.1 304 Not modified
  • 44.
  • 45.
    33 Pagination with queryparameters • With a page number: ?page=23 • can also specify a page size • might get odd results when insertions happen • With a cursor: ?cursor=34ea3fd6 • insertion-friendly • With a semantic parameter: ?page=A • interesting when limited / discrete number of pages
  • 46.
    34 Pagination with acceptrange header • Accept range header not just for bytes GET /users HTTP/1.1 206 Partial content Accept-Ranges: users Content-Range: users 0-9/200 GET /users Range: users=0-9
  • 47.
  • 48.
    36 Wrapped collections • Preferunwrapped collections • unless there’s specific collection payload metadata
 (example: photo album details) • pagination are better in HTTP headers GET /tickets Content-Type: application/json { data: [ { id: 1, ... }, { id: 2, ... } ] } GET /tickets Content-Type: application/json [ { id: 1, ... }, { id: 2, ... } ]
  • 49.
    37 Common HTTP StatusCodes — 3xx
  • 50.
    37 Common HTTP StatusCodes — 3xx
  • 51.
    37 Common HTTP StatusCodes — 3xx
  • 52.
    37 Common HTTP StatusCodes — 3xx
  • 53.
    37 Common HTTP StatusCodes — 3xx
  • 54.
    37 Common HTTP StatusCodes — 3xx
  • 55.
    38 Common HTTP StatusCodes — 4xx
  • 56.
    38 Common HTTP StatusCodes — 4xx
  • 57.
    38 Common HTTP StatusCodes — 4xx
  • 58.
    38 Common HTTP StatusCodes — 4xx
  • 59.
    38 Common HTTP StatusCodes — 4xx
  • 60.
    38 Common HTTP StatusCodes — 4xx
  • 61.
    39 Provide helpful errorpayloads • No definitive standard yet • http problem proposal and vnd-error mime type HTTP/1.1 403 Forbidden Content-Type: application/problem+json Content-Language: en { "type": "https://example.com/probs/out-of-credit", "title": "You do not have enough credit.", "detail": "Your current balance is 30, but that costs 50.", "instance": "/account/12345/msgs/abc", "balance": 30, "accounts": ["/account/12345", "/account/67890"] }
  • 62.
    40 Common HTTP StatusCodes — 5xx
  • 63.
    40 Common HTTP StatusCodes — 5xx
  • 64.
    40 Common HTTP StatusCodes — 5xx
  • 65.
    40 Common HTTP StatusCodes — 5xx
  • 66.
    41 Treating unknown statuscodes • An unknown status code should be treated 
 as the first one of the family • 4xx — 400 generic client error • 5xx — 500 generic server error
  • 67.
  • 68.
    43 Rate limitation HTTP/1.1 200OK Date: Mon, 01 Jul 2013 17:27:06 GMT Status: 200 OK X-RateLimit-Limit: 60 X-RateLimit-Remaining: 56 X-RateLimit-Reset: 1372700873 Total number of requests allowed Number of requests left remaining window before the rate limit resets in UTC epoch seconds
  • 69.
  • 70.
    45 Selecting with queryparameters • Only 5 stars Chinese restaurants • GET https://api.co/restaurants?type=chinese&stars=5
  • 71.
  • 72.
    47 Filtering • Specify fieldsyou’re interested in: • GET https://api.co/users/123?fields=firstname,lastname,age • Specify excluded fields: • GET https://api.co/users/123?exclude=biography,resume • Specify a « style »: • GET https://api.co/users/123?style=compact
  • 73.
    48 Prefer… the preferheader GET /users/123 HTTP/1.1 Content-Type: application/json Prefer: return=minimal Vary: Prefer,Accept,Accept-Encoding HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Vary: Prefer,Accept,Accept-Encoding Preference-Applied: return=minimal Define different profiles: minimal, mobile, full…
  • 74.
    49 Expanding referenced resources •Use the dot notation to explicit you want sub-resources • GET https://api.co/users/123?fields=address.zip • user • name • address • zip • country • … • …
  • 75.
  • 76.
    51 Sorting • SQL-style • GEThttps://api.co/books?sort=title+DESC • GET https://api.co/books?sort=title+DESC,author+ASC • Sort + asc/desc combo • GET https://api.co/books?sort=title&desc=title • GET https://api.co/books? sort=title,author&desc=title&asc=author
  • 77.
  • 78.
    53 Searching • Combien variousfiltering fields • Or provide a full-blown query language
  • 79.
  • 80.
    55 Different approaches forAPI versioning • Most frequent, in the URL: • https://api.com/v2/restaurants/1234 • Custom header: • X-API-Version: 2 • Less frequent, with an accept header • clients don’t have to change endpoint, but update headers GET /restaurants Accept: application/vnd.restaurants.v2+json
  • 81.
  • 82.
  • 83.
    58 Pros & Consof hypermedia • Pros • more generic clients • can palliate the need for API versioning • Cons • heavier payload (think mobile devices w/ bad connectivity) • clients still need to understand what links are about and how to represent them in their UI
  • 84.
  • 85.
    60 Lots of choice •HAL • JSON-LD • Collection+JSON • SIREN • … • Which to chose from? • no real consensus yet • but HAL seems quite common
  • 86.
    61 A word aboutIDs for linked resources • If you’re tempted to go your own way for hypermedia… • Be sure to define direct links to resources • photos: [http://news.co/articles/123/photos/654,
 http://news.co/articles/123/photos/659] • Not mere IDs for which API clients need to figure out the exact resource location (error-prone) • photos: [654, 659]
  • 87.
    62 Another word aboutIDs • Usually avoid counter-type IDs: 1, 2, 3, 4… • Prefer UUIDs • makes it harder for malignant users 
 to scan & discover existing resources • auto-incrementing IDs might not be unique 
 in distributed systems
  • 88.
    HAL I’m sorry Dave,I can do Hypermedia
  • 89.
    64 HAL approach GET https://api.com/player/1234567890 HTTP/1.1200 OK { "_links": { "self": { "href": "https://api.com/player/1234567890" }, "friends": { "href": "https://api.com/player/1234567890/friends" } }, "playerId": "1234567890", "name": "Kevin Sookocheff", "alternateName": "soofaloofa", "image": "https://api.com/player/1234567890/avatar.png" } Special _links property
  • 90.
  • 91.
    66 API design resources •http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api • https://github.com/paypal/api-standards/blob/master/api-style-guide.md • http://blog.octo.com/en/design-a-rest-api/ • https://github.com/interagent/http-api-design/blob/master/SUMMARY.md • http://sookocheff.com/post/api/on-choosing-a-hypermedia-format/ • http://www.troyhunt.com/2014/02/your-api-versioning-is-wrong-which-is.html
  • 92.
    Thanks for yourattention
  • 93.