Slide 1

Slide 1 text

API Design Patterns Beyond REST Jeremiah Lee • SXSW • 2014-03-07T15:30:00-06:00

Slide 2

Slide 2 text

#DX @Jeremiah @JeremiahLee

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

"Don't make me think!" is something users get to scream at us, as API providers. 
 It is not how API providers get to approach API design.

Slide 5

Slide 5 text

The secret to  machines talking to machines  is to speak human first.

Slide 6

Slide 6 text

Brief history…

Slide 7

Slide 7 text

Credit: Marsh Gardiner, @earth2marsh Brian Mulloy, @landlessness

Slide 8

Slide 8 text

Credit: Marsh Gardiner, @earth2marsh Brian Mulloy, @landlessness

Slide 9

Slide 9 text

Credit: Marsh Gardiner, @earth2marsh Brian Mulloy, @landlessness Nerd fights.

Slide 10

Slide 10 text

Credit: Marsh Gardiner, @earth2marsh Brian Mulloy, @landlessness http://www.flickr.com/photos/45713725@N00/8573651373/in/photolist-e4CcRp-biQQKX-7YZVKs http://kevinwarnock.com/2010/02/

Slide 11

Slide 11 text

Credit: Marsh Gardiner, @earth2marsh Brian Mulloy, @landlessness

Slide 12

Slide 12 text

RV: General Philosophy • User adoption is the highest priority. • Know your users. • Opt for the most obvious. • Use-cases over technical purity. • Errors and corrective guidance matter a lot. • No design is perfect. Accept that change will happen. • It’s your responsibility to eliminate pain.

Slide 13

Slide 13 text

HTTP: 3 places for data • Method and URL • Headers • Body

Slide 14

Slide 14 text

REQUEST GET http://api.example.com/1/users.json?sort=asc ! Host: api.example.com Accept: application/json Accept-Language: en-US,en Accept-Encoding: gzip, deflate Authorization: Bearer 1a2b3c4d5e6f7g8h9i0j Connection: keep-alive If-None-Match: "1394292863" RESPONSE HTTP/1.1 200 OK Content-Language: en Date: Sat, 08 Mar 2014 15:53:58 GMT Vary: Accept-Encoding Content-Length: 827 Content-Type: application/json;charset=UTF-8 ETag: "1394292864" ! { "users": [ { "aboutMe": "Start simple. Dream big. Do good. Be well.", "avatar": "https://d6y8zfzc2qfsl.cloudfront.net/F9C84BE0-52C5-AF63-2E5 "avatar150": "https://d6y8zfzc2qfsl.cloudfront.net/F9C84BE0-52C5-AF63- "city": "San Francisco", "country": "US", "dateOfBirth": "1984-01-15",

Slide 15

Slide 15 text

Resources & Collections GET https://api.example.com/1/articles GET https://api.example.com/1/articles/{article-id} HTTP 1.1/200 OK

Slide 16

Slide 16 text

Creating Resources POST https://api.example.com/1/articles PUT https://api.example.com/1/articles/{article-id} HTTP 1.1/201 Created HTTP 1.1/202 Accepted (pending)

Slide 17

Slide 17 text

Updating Resources PUT https://api.example.com/1/articles/{article-id} PATCH https://api.example.com/1/articles/{article-id} HTTP 1.1/200 OK HTTP 1.1/202 Accepted (pending)

Slide 18

Slide 18 text

Deleting Resources DELETE https://api.example.com/1/articles/{article-id} HTTP 1.1/204 No Content

Slide 19

Slide 19 text

More Resource Verbs POST https://api.example.com/1/articles/{article-id}/publish POST https://api.example.com/1/articles/{article-id}/star HTTP 1.1/200 OK HTTP 1.1/202 Accepted (pending)

Slide 20

Slide 20 text

RV on the Resource • Content Type GET /api/articles/1234 HTTP/1.1 Accept: application/vnd.api.article+json; version=2.0 GET /2/articles/1234.json —VS— þ

Slide 21

Slide 21 text

RV on the Resource • Content Type • Dates Twitter "created_at": "Thu Nov 03 05:19:38 +0000 2011" Foursquare: "createdAt": 1320296464 Bing "DateTime": "2011-10-29T09:35:00Z" þ

Slide 22

Slide 22 text

RV on the Resource • Content Type • Dates • Arrays vs Objects "supportedLanguages": [ { "country": "United States", "languages": ["English", "Spanish"] }, { "country": "Canada", "languages": ["English", "French"] } ] "supportedLanguages": { "us": { "country": "United States", "languages": ["English", "Spanish"] }, "ca": { "country": "Canada", "languages": ["English", "French"] } }

Slide 23

Slide 23 text

RV on the Collection • Sorting
 GET /articles?orderby=date&sort=desc

Slide 24

Slide 24 text

RV on the Collection • Sorting • Pagination
 "pagination": {
 "offset": 10,
 "limit": 10,
 "afterDate" | "beforeDate": "2014-01-15",
 "sort": "asc" | "desc",
 "previous": "https://api.example.com/1/articles.json? offset=0&limit=10&afterDate=2014-01-15&sort=desc",
 "next": "https://api.example.com/1/articles.json? offset=20&limit=10&afterDate=2014-01-15&sort=desc"
 }

Slide 25

Slide 25 text

RV on the Collection • Sorting • Pagination • Searching
 GET /articles?search=SXSW

Slide 26

Slide 26 text

RV on the Collection • Sorting • Pagination • Searching • Filtering
 From Elasticsearch
 POST /articles/filter { "filter": { "range": { "age": { "from": 10, "to": 20 } }
 } }

Slide 27

Slide 27 text

RV on the Collection • Sorting • Pagination • Searching • Filtering • Syncing
 GET /articles/sync?since=2014-01-15T09:15Z
 
 Check out RFC-6902, "JSON Patch"

Slide 28

Slide 28 text

RV on the URL • Collection-Resource
 GET /articles
 GET /articles/{article-id} • Relationships: dependent or independent
 GET /articles/{article-id}/comments/{comment-id}
 GET /articles and GET /authors • Or name the relationship
 GET /partnerships/{partnership-id} • Provide conveniences
 GET https://graph.facebook.com/me/likes

Slide 29

Slide 29 text

Errors Happen • Use the best HTTP error code. 400 Bad Request (you messed up something) 401 Unauthorized (Authorization invalid for some reason) 403 Forbidden (you don’t have permission) 404 Not Found (doesn’t exist or you can’t know it exists) 409 Conflict 429 Too Many Requests 5xx API is frakked up

Slide 30

Slide 30 text

Errors Happen • Use the right error code. • If using JSON, "error" as top level property. { "error": { "status": 400, "code": "bad_request", "message": "The 'email' parameter is required.", "helpUrl": "https://dev.example.com/docs/blah" } }

Slide 31

Slide 31 text

Errors Happen • Use the right error code. • If using JSON, “error” as top level property. • Be descriptive. • Be corrective. • Be informative.

Slide 32

Slide 32 text

Authentication • OAuth 1.0a, “2.0” • Basic Auth https://jeremiah:[email protected]/1/articles.json • Personal Access Tokens

Slide 33

Slide 33 text

Versioning • Have it. in the URL. GET /api/articles/1234 HTTP/1.1 Accept: application/vnd.api.article+json; version=2.0 GET /2/articles/1234.json —VS— þ

Slide 34

Slide 34 text

Versioning • Have it. in the URL. • Prevent it.

Slide 35

Slide 35 text

Versioning • Have it. in the URL. • Prevent it. • Mitigate it.

Slide 36

Slide 36 text

Versioning • Have it. in the URL. • Prevent it. • Mitigate it.

Slide 37

Slide 37 text

Versioning • Have it. in the URL. • Prevent it. • Mitigate it. • Do it. • Test it. • Communicate it. • Incentivize upgrading. Measure it. • Support it. for longer than you want.

Slide 38

Slide 38 text

The secret to  machines talking to machines  is to speak human first.

Slide 39

Slide 39 text

Thank you for your time. ! More content available at
 http://dx.jeremiahlee.com ! @ResourceVerb • @JeremiahLee Please support the
 Electronic Frontier Foundation

Slide 40

Slide 40 text

Q & A WEBHOOKS BATCHING REQUESTS OPTIONS HEADER LIMITING RESPONSE FIELDS API ANALYTICS SANDBOX ENVIRONMENTS 3rd PARTY LOGS ANTI-PATTERNS GZIP COOL USES OF HEADERS DEV USABILITY TESTING camelCasing http://dx.jeremiahlee.com • @ResourceVerb • @JeremiahLee

Slide 41

Slide 41 text

No content