$30 off During Our Annual Pro Sale. View Details »

Good to Great: API Design Patterns Beyond REST

Good to Great: API Design Patterns Beyond REST

Jeremiah Lee

March 08, 2014
Tweet

More Decks by Jeremiah Lee

Other Decks in Programming

Transcript

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

    View Slide

  2. #DX
    @Jeremiah @JeremiahLee

    View Slide

  3. View Slide

  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.

    View Slide

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

    View Slide

  6. Brief history…

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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/

    View Slide

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

    View Slide

  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.

    View Slide

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

    View Slide

  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",

    View Slide

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

    View Slide

  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)

    View Slide

  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)

    View Slide

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

    View Slide

  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)

    View Slide

  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—
    þ

    View Slide

  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"
    þ

    View Slide

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

    View Slide

  23. RV on the Collection
    • Sorting

    GET /articles?orderby=date&sort=desc

    View Slide

  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"

    }

    View Slide

  25. RV on the Collection
    • Sorting
    • Pagination
    • Searching

    GET /articles?search=SXSW

    View Slide

  26. RV on the Collection
    • Sorting
    • Pagination
    • Searching
    • Filtering

    From Elasticsearch

    POST /articles/filter
    {
    "filter": {
    "range": {
    "age": { "from": 10, "to": 20 }
    }

    }
    }

    View Slide

  27. RV on the Collection
    • Sorting
    • Pagination
    • Searching
    • Filtering
    • Syncing

    GET /articles/sync?since=2014-01-15T09:15Z


    Check out RFC-6902, "JSON Patch"

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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—
    þ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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.

    View Slide

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

    View Slide

  39. Thank you for your time.
    !
    More content available at

    http://dx.jeremiahlee.com
    !
    @ResourceVerb • @JeremiahLee
    Please support the

    Electronic Frontier Foundation

    View Slide

  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

    View Slide

  41. View Slide