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

API Design: It's Not Rocket Surgery (PHPUK13)

Dave Ingram
February 22, 2013

API Design: It's Not Rocket Surgery (PHPUK13)

The talk I gave at PHPUK13 on Friday 22nd February in (a very packed!) Track 3.

Dave Ingram

February 22, 2013
Tweet

More Decks by Dave Ingram

Other Decks in Programming

Transcript

  1. Who am I? • Senior operations engineer at DataSift •

    Was developer/RM at GroupSpaces for 41/2 years • Way too many projects • Involved in open source, including Phabricator • Occasionally found at London Hackspace • Twitter: @dmi • Github: dingram
  2. Why am I giving this talk? • I’ve built a

    number of APIs • Both for GroupSpaces and my own projects • Sadly most are not public (yet!) • I’m also a consumer of many other APIs • Twitter • Foursquare • Tumblr • TfL • Spotify • . . . blah blah blah. . . • I’m opinionated
  3. 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
  4. 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
  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
  6. • GET = get() • PUT = setAll() / new

    Obj($id) • POST = new Obj() / doStuff() / set() • DELETE = delete() • HEAD ≈ getMetadata() • OPTIONS ≈ reflection/permissions
  7. PUT and DELETE are idempotent, which means they have the

    same effect even if they’re repeated
  8. 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
  9. 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
  10. 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.
  11. • ETag – A unique tag for the content •

    If-(None-)Match – Check ETag • If-(Un)Modified-Since – Is it newer? • Cache-Control – Can it be cached? • Expires – How long is it valid? • Vary – Additional caching rules
  12. Then again, the author of OAuth2 has now advised not

    upgrading from OAuth 1.0a and either using OAuth 1.0a for new sites or staying close to a large provider’s implementation
  13. { "meta": { "code": 2 , "dev_notes ": [ "This

    endpoint is deprecated" ] }, "response ": { ... } }
  14. *Hypertext as the Engine of Application State HATEOAS* is a

    nice idea, although it’s very verbose (but useful for building an API explorer)
  15. Timestamps • ISO-8601 2 12- 5- 3T19: : Z Human-readable,

    but needs parsing • UTC seconds since epoch: 1336 716 Easily machine-usable
  16. Encourage use of request headers: • GET: • If-Modified-Since •

    If-None-Match • POST/PUT/DELETE: • If-Unmodified-Since • If-Match
  17. Useful status codes: 4 5 Method Not Allowed 4 6

    Not Acceptable 412 Precondition Failed 428 Precondition Required* 429 Too Many Requests* *New in RFC6585
  18. PUT /v1/wiki/dealing -with -conflicts HTTP /1.1 Host: api.com Content -Type:

    text/html ... 428 Precondition Required ETag: "x-rev -11294" Last -Modified: Sat , 18 Feb 2 12 11: 9:21 GMT ...
  19. PUT /v1/wiki/dealing -with -conflicts HTTP /1.1 Host: api.com Content -Type:

    text/html ... 428 Precondition Required ETag: "x-rev -11294" Last -Modified: Sat , 18 Feb 2 12 11: 9:21 GMT ...
  20. PUT /v1/wiki/dealing -with -conflicts HTTP /1.1 Host: api.com Content -Type:

    text/html ... 428 Precondition Required ETag: "x-rev -11294" Last -Modified: Sat , 18 Feb 2 12 11: 9:21 GMT ...
  21. PUT /v1/wiki/dealing -with -conflicts HTTP /1.1 Host: api.com Content -Type:

    text/html ... 428 Precondition Required ETag: "x-rev -11294" Last -Modified: Sat , 18 Feb 2 12 11: 9:21 GMT ...
  22. PUT /v1/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 ...
  23. PUT /v1/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 ...
  24. PUT /v1/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 ...
  25. PUT /v1/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 ...
  26. Things to measure Counters: HTTP status (200, 400, 500, .

    . . ) Tokens issued Token refreshes Clients created Client usage Auth successes Auth failures Auth grants Auth rejections DB queries API version/release Client type . . . Avg response time: Auth requests General requests Specific subsystems . . . Other Memory usage Client location . . .
  27. Thanks! Any questions? Feedback via joind.in: http://joind.in/8 45 or #apirocketsurgery

    or @dmi Slides: http://www.dmi.me.uk/talks/ Built in L ATEX Inspired by: http://goo.gl/ mT55