+ All Categories
Home > Internet > The never-ending REST API design debate -- Devoxx France 2016

The never-ending REST API design debate -- Devoxx France 2016

Date post: 21-Apr-2017
Category:
Upload: restlet
View: 1,241 times
Download: 1 times
Share this document with a friend
96
The never-ending REST API design debate Guillaume Laforge Restlet — the Web API platform Chair of the Apache Groovy PMC @glaforge
Transcript
Page 1: The never-ending REST API design debate -- Devoxx France 2016

The never-ending REST API design debateGuillaume Laforge Restlet — the Web API platform Chair of the Apache Groovy PMC @glaforge

Page 2: The never-ending REST API design debate -- Devoxx France 2016
Page 3: The never-ending REST API design debate -- Devoxx France 2016

Devoxx Promo Code: ctwdevoxxfrhttp://www.manning.com/koenig2/

GROOVY IN ACTION 2ND EDITION

Page 4: The never-ending REST API design debate -- Devoxx France 2016

We know about APIs!

http://restlet.com

Page 5: The never-ending REST API design debate -- Devoxx France 2016

We know about APIs!

http://restlet.com

Page 6: The never-ending REST API design debate -- Devoxx France 2016

ROY FIELDING

REST DISSERTATION

Page 7: The never-ending REST API design debate -- Devoxx France 2016

ROY FIELDING

REST DISSERTATION

Principled design of the modern

Web architecture

Page 8: The never-ending REST API design debate -- Devoxx France 2016

5

Representational State TransferArchitectural properties

• Performance • Scalability • Simplicity • Modifiability • Visibility • Portability • Reliability

Architectural constraints

• Client-server • Stateless • Cacheable • Layered system • Code on demand (optional) • Uniform interface

Page 9: The never-ending REST API design debate -- Devoxx France 2016

6

REST — Uniform interface• Identification of resources

• Manipulation of resources through representations

• Self-descriptive messages

• HATEOAS (Hypermedia As The Engine Of Application State)

Page 10: The never-ending REST API design debate -- Devoxx France 2016

6

REST — Uniform interface• Identification of resources

• Manipulation of resources through representations

• Self-descriptive messages

• HATEOAS (Hypermedia As The Engine Of Application State)

Resource as URIs http://api.co/cars/123

Page 11: The never-ending REST API design debate -- Devoxx France 2016

6

REST — Uniform interface• Identification of resources

• Manipulation of resources through representations

• Self-descriptive messages

• HATEOAS (Hypermedia As The Engine Of Application State)

Resource as URIs http://api.co/cars/123

JSON, XML…

Page 12: The never-ending REST API design debate -- Devoxx France 2016

6

REST — Uniform interface• Identification of resources

• Manipulation of resources through representations

• Self-descriptive messages

• HATEOAS (Hypermedia As The Engine Of Application State)

Resource as URIs http://api.co/cars/123

JSON, XML…

HTTP GET, POST, PUT, DELETE media types, cacheability…

Page 13: The never-ending REST API design debate -- Devoxx France 2016

6

REST — Uniform interface• Identification of resources

• Manipulation of resources through representations

• Self-descriptive messages

• HATEOAS (Hypermedia As The 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…

Page 14: The never-ending REST API design debate -- Devoxx France 2016

7

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 Update an individual car

Delete all the cars Delete an individual car

Page 15: The never-ending REST API design debate -- Devoxx France 2016

NOUNS

ARE GOOD

VERBS

ARE BAD

Page 16: The never-ending REST API design debate -- Devoxx France 2016

9

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

Page 17: The never-ending REST API design debate -- Devoxx France 2016
Page 18: The never-ending REST API design debate -- Devoxx France 2016

11

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’

Page 19: The never-ending REST API design debate -- Devoxx France 2016

Camel case?

Page 20: The never-ending REST API design debate -- Devoxx France 2016

Camel case?

Snake case!

Page 21: The never-ending REST API design debate -- Devoxx France 2016

13

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!

Page 22: The never-ending REST API design debate -- Devoxx France 2016

14

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

Page 23: The never-ending REST API design debate -- Devoxx France 2016

API PARAMETERS RULE OF THUMBS

Page 24: The never-ending REST API design debate -- Devoxx France 2016

16

API parameters — rule of thumbs• Path

• required, resource identifier • Query

• optional, query collections • Body

• resource specific logic • Header

• global, platform-wide

Page 25: The never-ending REST API design debate -- Devoxx France 2016

17

HTTP Status Code Map http://bit.ly/stcode

Page 26: The never-ending REST API design debate -- Devoxx France 2016

18

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 :-(

Page 27: The never-ending REST API design debate -- Devoxx France 2016

19

Common HTTP Status Codes — 1xx

Page 28: The never-ending REST API design debate -- Devoxx France 2016

20

Common HTTP Status Codes — 2xx

Page 29: The never-ending REST API design debate -- Devoxx France 2016

20

Common HTTP Status Codes — 2xx

Page 30: The never-ending REST API design debate -- Devoxx France 2016

20

Common HTTP Status Codes — 2xx

Page 31: The never-ending REST API design debate -- Devoxx France 2016

20

Common HTTP Status Codes — 2xx

Page 32: The never-ending REST API design debate -- Devoxx France 2016

20

Common HTTP Status Codes — 2xx

Page 33: The never-ending REST API design debate -- Devoxx France 2016

20

Common HTTP Status Codes — 2xx

Page 34: The never-ending REST API design debate -- Devoxx France 2016

NOT JUST 200

201

202

204

206

Page 35: The never-ending REST API design debate -- Devoxx France 2016

Anti-pattern: returns 200

for everything, even errors!

Page 36: The never-ending REST API design debate -- Devoxx France 2016

23

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

Page 37: The never-ending REST API design debate -- Devoxx France 2016

API navigation is important to make the API more discoverable

Page 38: The never-ending REST API design debate -- Devoxx France 2016

25

DHC by Restlet: API testing tool

Page 39: The never-ending REST API design debate -- Devoxx France 2016

26

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

Page 40: The never-ending REST API design debate -- Devoxx France 2016

27

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

Page 41: The never-ending REST API design debate -- Devoxx France 2016

28

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"

...

Page 42: The never-ending REST API design debate -- Devoxx France 2016

29

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

Page 43: The never-ending REST API design debate -- Devoxx France 2016

Caching!

Page 44: The never-ending REST API design debate -- Devoxx France 2016

31

Last-Modified

GET /users/123 Modified-Since: Wed, 13 Apr 2016 02:13:11 GMT

HTTP/1.1 200 OK Last-Modified: Fri, 15 Apr 2016 04:58:08 GMT

Page 45: The never-ending REST API design debate -- Devoxx France 2016

32

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

Page 46: The never-ending REST API design debate -- Devoxx France 2016

PAGINATION

Page 47: The never-ending REST API design debate -- Devoxx France 2016

34

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

Page 48: The never-ending REST API design debate -- Devoxx France 2016

35

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

Page 49: The never-ending REST API design debate -- Devoxx France 2016

Wrapped CollectionS

Page 50: The never-ending REST API design debate -- Devoxx France 2016

37

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, ... } ]

Page 51: The never-ending REST API design debate -- Devoxx France 2016

38

Common HTTP Status Codes — 3xx

Page 52: The never-ending REST API design debate -- Devoxx France 2016

38

Common HTTP Status Codes — 3xx

Page 53: The never-ending REST API design debate -- Devoxx France 2016

38

Common HTTP Status Codes — 3xx

Page 54: The never-ending REST API design debate -- Devoxx France 2016

38

Common HTTP Status Codes — 3xx

Page 55: The never-ending REST API design debate -- Devoxx France 2016

38

Common HTTP Status Codes — 3xx

Page 56: The never-ending REST API design debate -- Devoxx France 2016

38

Common HTTP Status Codes — 3xx

Page 57: The never-ending REST API design debate -- Devoxx France 2016

39

Common HTTP Status Codes — 4xx

Page 58: The never-ending REST API design debate -- Devoxx France 2016

39

Common HTTP Status Codes — 4xx

Page 59: The never-ending REST API design debate -- Devoxx France 2016

39

Common HTTP Status Codes — 4xx

Page 60: The never-ending REST API design debate -- Devoxx France 2016

39

Common HTTP Status Codes — 4xx

Page 61: The never-ending REST API design debate -- Devoxx France 2016

39

Common HTTP Status Codes — 4xx

Page 62: The never-ending REST API design debate -- Devoxx France 2016

39

Common HTTP Status Codes — 4xx

Page 63: The never-ending REST API design debate -- Devoxx France 2016

40

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"] }

Page 64: The never-ending REST API design debate -- Devoxx France 2016

41

Common HTTP Status Codes — 5xx

Page 65: The never-ending REST API design debate -- Devoxx France 2016

41

Common HTTP Status Codes — 5xx

Page 66: The never-ending REST API design debate -- Devoxx France 2016

41

Common HTTP Status Codes — 5xx

Page 67: The never-ending REST API design debate -- Devoxx France 2016

41

Common HTTP Status Codes — 5xx

Page 68: The never-ending REST API design debate -- Devoxx France 2016

42

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

Page 69: The never-ending REST API design debate -- Devoxx France 2016

RATE LIMITATION

Page 70: The never-ending REST API design debate -- Devoxx France 2016

44

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

Page 71: The never-ending REST API design debate -- Devoxx France 2016

ONE SIZE FITS

ALL

Different payloads for different consumers

Page 72: The never-ending REST API design debate -- Devoxx France 2016

46

Selecting with query parameters• Only 5 stars Chinese restaurants

• GET https://api.co/restaurants?type=chinese&stars=5

Page 73: The never-ending REST API design debate -- Devoxx France 2016

FILTERING

Page 74: The never-ending REST API design debate -- Devoxx France 2016

48

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

Page 75: The never-ending REST API design debate -- Devoxx France 2016

49

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…

Page 76: The never-ending REST API design debate -- Devoxx France 2016

50

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 • …

• …

Page 77: The never-ending REST API design debate -- Devoxx France 2016

SORTING

Page 78: The never-ending REST API design debate -- Devoxx France 2016

52

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

Page 79: The never-ending REST API design debate -- Devoxx France 2016

SEARCHING

Page 80: The never-ending REST API design debate -- Devoxx France 2016

54

Searching• Combine various filtering fields

• Or provide a full-blown query language

Page 81: The never-ending REST API design debate -- Devoxx France 2016

55

Search / filter / sort…• Also have a look at other approaches

• Facebook’s GraphQL • Netflix’s Falcor

Page 82: The never-ending REST API design debate -- Devoxx France 2016

v1

Page 83: The never-ending REST API design debate -- Devoxx France 2016

57

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

Page 84: The never-ending REST API design debate -- Devoxx France 2016

hypermedia

Page 85: The never-ending REST API design debate -- Devoxx France 2016

59

Richardson maturity model

Page 86: The never-ending REST API design debate -- Devoxx France 2016

60

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

Page 87: The never-ending REST API design debate -- Devoxx France 2016

CHANGE IS

UNAVOID

ABLE

Page 88: The never-ending REST API design debate -- Devoxx France 2016

62

Lots of choice• HAL • JSON-LD • Collection+JSON • SIREN • …

• Which to chose from? • no real consensus yet • but HAL seems quite common

Page 89: The never-ending REST API design debate -- Devoxx France 2016

63

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]

Page 90: The never-ending REST API design debate -- Devoxx France 2016

64

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

Page 91: The never-ending REST API design debate -- Devoxx France 2016

HAL

I’m sorry Dave, I can do Hypermedia

Page 92: The never-ending REST API design debate -- Devoxx France 2016

66

HAL approachGET 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

Page 93: The never-ending REST API design debate -- Devoxx France 2016

Resources

Page 94: The never-ending REST API design debate -- Devoxx France 2016

68

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

Page 95: The never-ending REST API design debate -- Devoxx France 2016

Thanks for your attention

Page 96: The never-ending REST API design debate -- Devoxx France 2016

Questions & Answers


Recommended