Good to Great: API Design Patterns Beyond REST

Good to Great: API Design Patterns Beyond REST

A1bbf2de1c3ef1db1c54d77d2ab17de2?s=128

Jeremiah Lee

March 08, 2014
Tweet

Transcript

  1. API Design Patterns Beyond REST Jeremiah Lee • SXSW •

    2014-03-07T15:30:00-06:00
  2. #DX @Jeremiah @JeremiahLee

  3. None
  4. "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.
  5. The secret to  machines talking to machines  is

    to speak human first.
  6. Brief history…

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

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

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

  10. 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/

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

  12. 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.
  13. HTTP: 3 places for data • Method and URL •

    Headers • Body
  14. 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",
  15. Resources & Collections GET https://api.example.com/1/articles GET https://api.example.com/1/articles/{article-id} HTTP 1.1/200 OK

  16. 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)
  17. 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)
  18. Deleting Resources DELETE https://api.example.com/1/articles/{article-id} HTTP 1.1/204 No Content

  19. 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)
  20. 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— þ
  21. 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" þ
  22. 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"] } }
  23. RV on the Collection • Sorting
 GET /articles?orderby=date&sort=desc

  24. 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"
 }
  25. RV on the Collection • Sorting • Pagination • Searching


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

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

    • Filtering • Syncing
 GET /articles/sync?since=2014-01-15T09:15Z
 
 Check out RFC-6902, "JSON Patch"
  28. 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
  29. 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
  30. 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" } }
  31. Errors Happen • Use the right error code. • If

    using JSON, “error” as top level property. • Be descriptive. • Be corrective. • Be informative.
  32. Authentication • OAuth 1.0a, “2.0” • Basic Auth https://jeremiah:myPasswordYo@api.example.com/1/articles.json •

    Personal Access Tokens
  33. 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— þ
  34. Versioning • Have it. in the URL. • Prevent it.

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

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

    • Mitigate it.
  37. 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.
  38. The secret to  machines talking to machines  is

    to speak human first.
  39. Thank you for your time. ! More content available at


    http://dx.jeremiahlee.com ! @ResourceVerb • @JeremiahLee Please support the
 Electronic Frontier Foundation
  40. 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
  41. None