Upgrade to Pro — share decks privately, control downloads, hide ads and more …

API Design: it's not rocket surgery (PHPNW2012)

Dave Ingram
October 06, 2012

API Design: it's not rocket surgery (PHPNW2012)

A slightly-updated version of my API design talk, compressed into 20 minutes for the PHPNW2012 unconference.

Dave Ingram

October 06, 2012
Tweet

More Decks by Dave Ingram

Other Decks in Technology

Transcript

  1. API design
    It’s Not Rocket Surgery
    Dave Ingram
    @dmi
    October 6, 2012

    View full-size slide

  2. Who am I?
    • Coder and Release Manager at GroupSpaces
    • Worked there for over 41/2 years
    • Twitter: @dmi
    • Github: dingram
    • Way too many projects of my own
    • Also involved in open source, including Phabricator
    • Occasionally found at London Hackspace

    View full-size slide

  3. Feedback/thoughts
    on Twitter:
    #apirocketsurgery
    (or @dmi)

    View full-size slide

  4. What this isn’t

    View full-size slide

  5. T
    T
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    EST
    EST
    ST
    ST
    ST
    T
    T
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    R
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    R
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    R
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    RES
    RES
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    R
    R
    R
    RE
    RE
    RE
    RES
    RES
    REST
    R

    View full-size slide

  6. T
    T
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    EST
    EST
    ST
    ST
    ST
    T
    T
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    R
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    R
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    R
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    RES
    RES
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    R
    R
    R
    RE
    RE
    RE
    RES
    RES
    REST
    R

    View full-size slide

  7. T
    T
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    EST
    EST
    ST
    ST
    ST
    T
    T
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    R
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    R
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    R
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    RES
    RES
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    REST
    R
    R
    R
    RE
    RE
    RE
    RES
    RES
    REST
    R

    View full-size slide

  8. There’s so much more!

    View full-size slide

  9. URLs
    verbs
    headers

    View full-size slide

  10. URLs
    verbs
    headers
    authentication

    View full-size slide

  11. URLs
    verbs
    headers
    authentication
    formats

    View full-size slide

  12. URLs
    verbs
    headers
    authentication
    formats
    validity

    View full-size slide

  13. URLs
    verbs
    headers
    authentication
    formats
    validity
    documentation

    View full-size slide

  14. DOCUMENTATION

    View full-size slide

  15. DOCUMENTATION
    (later)

    View full-size slide

  16. Part 1: URLs

    View full-size slide

  17. Make them
    versioned

    View full-size slide

  18. Make them
    versioned,
    hackable

    View full-size slide

  19. Make them
    versioned,
    hackable &
    meaningful

    View full-size slide

  20. http://api.com/v1/

    View full-size slide

  21. http://api.com/v1/users/

    View full-size slide

  22. http://api.com/v1/users/31337

    View full-size slide

  23. http://api.com/v1/users/31337/posts/

    View full-size slide

  24. Look at URLs from a
    consumer perspective

    View full-size slide

  25. They don’t care about
    internal implementation
    details

    View full-size slide

  26. Use common sense

    View full-size slide

  27. Don’t be afraid of
    the query string

    View full-size slide

  28. Use query arguments to
    filter output or for (some)
    alternate representations

    View full-size slide

  29. Good: searching & verbosity
    Bad: output format control
    (XML vs JSON)

    View full-size slide

  30. Part 2: Verbs

    View full-size slide

  31. (in terms of model
    operations)

    View full-size slide

  32. • GET = get()
    • PUT = setAll() / new Obj($id)
    • POST = new Obj() / doStuff() / set()
    • DELETE = delete()
    • HEAD ≈ getMetadata()
    • OPTIONS ≈ Reflection

    View full-size slide

  33. Must at least support GET/POST

    View full-size slide

  34. Can emulate PUT/DELETE

    View full-size slide

  35. For example:
    POST http://api.com/foo/456!PUT
    POST http://api.com/foo/123!DELETE

    View full-size slide

  36. Remember that POST can
    have side-effects and is
    never cached

    View full-size slide

  37. PUT and DELETE are
    idempotent, which means
    they can be repeated
    with same effect

    View full-size slide

  38. HEAD is rare and
    can probably be ignored

    View full-size slide

  39. OPTIONS is used by CORS,
    but otherwise rare

    View full-size slide

  40. Cross-Origin Resource Sharing

    View full-size slide

  41. A way to allow in-browser
    cross-origin XMLHTTPRequests
    Support: FF3.5+, Chrome 4+, Safari 4+, Opera 12+,
    IE8+ (partial), IE10+ (full), iOS 3.2+, Android 2.1+
    http://www.w3.org/TR/cors/
    http://caniuse.com/cors

    View full-size slide

  42. Origin & Allow-Origin
    A way to allow in-browser
    cross-origin XMLHTTPRequests
    Support: FF3.5+, Chrome 4+, Safari 4+, Opera 12+,
    IE8+ (partial), IE10+ (full), iOS 3.2+, Android 2.1+
    http://www.w3.org/TR/cors/
    http://caniuse.com/cors

    View full-size slide

  43. Part 3: Headers

    View full-size slide

  44. Headers are important too!

    View full-size slide

  45. Some headers let you be
    clever

    View full-size slide

  46. Accept
    The MIME types the client will accept.
    No need to use file extensions to decide
    what content type to serve!
    Accept-Language
    The languages the client will accept.
    No need to ask clients or (worse) just
    assume English responses.

    View full-size slide

  47. Some headers reduce traffic
    (important for mobile)

    View full-size slide

  48. • ETag – A unique tag for the content
    • If-(None-)Match – Check ETag
    • If-Modified-Since – Is it newer?
    • Cache-Control – Can it be cached?

    View full-size slide

  49. Beware: some proxies may
    not pass custom headers

    View full-size slide

  50. Part 4: Authentication &
    Authorization

    View full-size slide

  51. OAuth2 over HTTPS

    View full-size slide

  52. Much simpler than OAuth 1.0

    View full-size slide

  53. Many libraries for OAuth2
    for many platforms as
    it’s a popular standard

    View full-size slide

  54. If you really care about
    security use OAuth2-MAC

    View full-size slide

  55. OAuth2-MAC uses signatures
    instead of bearer tokens,
    so secrets stay secret

    View full-size slide

  56. Then again, the author of OAuth2 has now
    advised going back to OAuth 1.0a so
    YMMV

    View full-size slide

  57. Part 5: Formats

    View full-size slide

  58. Sane default: JSON, plus
    envelope with metadata

    View full-size slide

  59. {
    "meta": {
    "code": 2 ,
    "dev_notes ": [
    "This endpoint is deprecated"
    ]
    },
    "response ": {
    ...
    }
    }

    View full-size slide

  60. Use XML if you must,
    or if users really want it

    View full-size slide

  61. HATEOAS tends to be verbose
    and people may hate you
    (unless they’re building an API explorer)

    View full-size slide

  62. At the very most,
    HATEOAS should be opt-in

    View full-size slide

  63. Don’t forget: mobile
    bandwidth is still very limited

    View full-size slide

  64. Timestamps
    • ISO-8601 2 12- 5- 3T19: : Z
    Human-readable, but needs parsing
    • UTC seconds since epoch: 1336 716
    Easily machine-usable

    View full-size slide

  65. Should your API really be
    human-readable?
    It’s better to help your
    consumers.

    View full-size slide

  66. Part 6: Data Validity

    View full-size slide

  67. Allow your consumers
    to cache data
    whenever possible

    View full-size slide

  68. Encourage use of request headers:
    • GET:
    • If-Modified-Since
    • If-None-Match
    • POST/PUT/DELETE:
    • If-Unmodified-Since
    • If-Match

    View full-size slide

  69. Return useful response headers:
    • Last-Modified
    • Expires
    • ETag
    • Cache-Control

    View full-size slide

  70. Deal with preconditions and
    give correct response codes

    View full-size slide

  71. For example:
    ETag and Last-Modified
    can help prevent race
    conditions

    View full-size slide

  72. PUT /wiki/dealing -with -conflicts HTTP /1.1
    Host: api.com
    If -Unmodified -Since: Sat , 18 Feb 2 12 11: 9:21 GMT
    If -Match: "x-rev -11294"
    Content -Type: text/html
    ...
    412 Precondition Failed
    ETag: "x-rev -11467"
    Last -Modified: Sat , 25 Feb 2 12 14:42:53 GMT
    ...

    View full-size slide

  73. PUT /wiki/dealing -with -conflicts HTTP /1.1
    Host: api.com
    If -Unmodified -Since: Sat , 18 Feb 2 12 11: 9:21 GMT
    If -Match: "x-rev -11294"
    Content -Type: text/html
    ...
    412 Precondition Failed
    ETag: "x-rev -11467"
    Last -Modified: Sat , 25 Feb 2 12 14:42:53 GMT
    ...

    View full-size slide

  74. PUT /wiki/dealing -with -conflicts HTTP /1.1
    Host: api.com
    If -Unmodified -Since: Sat , 18 Feb 2 12 11: 9:21 GMT
    If -Match: "x-rev -11294"
    Content -Type: text/html
    ...
    412 Precondition Failed
    ETag: "x-rev -11467"
    Last -Modified: Sat , 25 Feb 2 12 14:42:53 GMT
    ...

    View full-size slide

  75. PUT /wiki/dealing -with -conflicts HTTP /1.1
    Host: api.com
    If -Unmodified -Since: Sat , 18 Feb 2 12 11: 9:21 GMT
    If -Match: "x-rev -11294"
    Content -Type: text/html
    ...
    412 Precondition Failed
    ETag: "x-rev -11467"
    Last -Modified: Sat , 25 Feb 2 12 14:42:53 GMT
    ...

    View full-size slide

  76. New status codes in RFC6585:
    428 Precondition Required
    429 Too Many Requests

    View full-size slide

  77. Part 7: Documentation

    View full-size slide

  78. Documentation is important

    View full-size slide

  79. If people can’t understand
    your API, they won’t use it

    View full-size slide

  80. Use examples liberally. . .
    and make sure they’re both
    up-to-date and correct!

    View full-size slide

  81. Assume nothing;
    explain everything

    View full-size slide

  82. Try getting people you know
    to build something using
    only your own API docs

    View full-size slide

  83. Thanks!
    http://dmi.me.uk/talks/
    Feedback via Twitter:
    #apirocketsurgery or @dmi
    Built in L
    ATEX Inspired by: http://goo.gl/ mT55

    View full-size slide