Save 37% off PRO during our Black Friday Sale! »

Building RESTful APIs

Building RESTful APIs

Discussion of how to design, test, and implement CRUD (commonly referred to as RESTful) APIs and how HATEOAS transforms a CRUD API into a REST API. Tips/tricks for sticky areas like versioning, URI extensions, and partial updates. Talk given at the 10/27/2011 San Francisco Ruby on Rails Meetup.

D283895e908601709fd493caf8fe2699?s=128

Joseph Ruscio

October 28, 2011
Tweet

Transcript

  1. Building RESTful APIs Friday, October 28, 2011

  2. metrics.librato.com Consumes arbitrary time series data Store it, visualize it,

    analyze it Query it back out from API Rich client interface Librato Metrics Friday, October 28, 2011
  3. metrics.librato.com Friday, October 28, 2011

  4. metrics.librato.com Friday, October 28, 2011

  5. metrics.librato.com “[hypertext constraint is] most often violated within so-called REST

    APIs ... adhere to them or choose some other buzzword for your API.” - Roy Fielding Friday, October 28, 2011
  6. metrics.librato.com CRUD API Resources identified/addressed by URI URI Templates HTTP-based

    interactions Friday, October 28, 2011
  7. metrics.librato.com CRUD: Resources Anything we expose to the Web Resources

    have representations JSON,XML,PNG Services exchange representations Friday, October 28, 2011
  8. metrics.librato.com CRUD: HTTP Verbs POST /res Unsafe GET /res/:id Safe

    PUT /res/:id Idempotent DELETE /res/:id Idempotent Friday, October 28, 2011
  9. metrics.librato.com Design Constraints JSON input/output x-form-urlencoded input for a bonus

    Basic HTTP Authentication over SSL Friday, October 28, 2011
  10. metrics.librato.com Doc. Driven Design URI template Markdown file per-resource URI,

    parameters, examples Production ready before a single LOC! Friday, October 28, 2011
  11. metrics.librato.com Friday, October 28, 2011

  12. metrics.librato.com Test Driven Dev. Simulate requests against the API Assert

    expectations about the response test-unit + rack-test Friday, October 28, 2011
  13. metrics.librato.com Test Driven Dev. def test_create_gauge params = {} params[:name]

    = "my_gauge" post "/gauges", params assert_equal 201, last_response.status assert last_response.original_headers["Location"] =~ /^\/v1\/gauges\/#{params[:name]}$/ end Friday, October 28, 2011
  14. metrics.librato.com rack-test-rest def test_crud name = "my_gauge" and period =

    60 #CREATE create_resource(:name => name, :description => desc) #READ gauge = read_resource(:id => name) assert_equal(name, gauge['name']) #UPDATE update_resource(:name => name, :period => 300) #DELETE delete_resource(:id => name) read_resource(:code => 404, :id => name) end Friday, October 28, 2011
  15. metrics.librato.com rack-test-rest Friday, October 28, 2011

  16. metrics.librato.com Implementation Thin layer over your models Sinatra + Sequel

    Resource per file Friday, October 28, 2011
  17. metrics.librato.com Implementation Friday, October 28, 2011

  18. metrics.librato.com Implementation post "/gauges" do unless params[:name] abort_params({:name => ["Must

    specify gauge name"]}) end if find_gauge(params[:name]) abort_unique({:name => ["Gauge name must be unique"]}) end gauge = create_gauge() halt_created("/gauges/#{gauge.name}") end Friday, October 28, 2011
  19. metrics.librato.com Friday, October 28, 2011

  20. metrics.librato.com URI Extensions URI should not imply representation Legacy from

    mapping URI’s to files Use content negotiation http://example.org/resource/123 Friday, October 28, 2011
  21. metrics.librato.com API Versioning http://v1.example.org/resource/123 http://example.org/v1/resource/123 http://example.org/resource/123 ?v=1 Accept: application/json;version=1 Friday,

    October 28, 2011
  22. metrics.librato.com Partial Updates PUT,POST,PATCH? PATCH - RFC5789 PATCH /resource/:id Friday,

    October 28, 2011
  23. metrics.librato.com HATEOAS CRUD is great except when it isn’t Hypermedia

    models state transitions Inclusion of links in representation Friday, October 28, 2011
  24. metrics.librato.com CRUD Pagination { "query":{ "total":128, "found":128, "offset":0, "length":100 },

    "gauges":[ { "name":"gauge1" }, { "name":"gauge2" }, ... ] } Friday, October 28, 2011
  25. metrics.librato.com REST Pagination { "next":{ "uri":"http://api.librato.com/gauges?offset=100”, "rel":"http://relations.librato.com/paginate", "media_type":"application/vnd.librato+json" }, "gauges":[

    { "name":"gauge1" }, { "name":"gauge2" }, ... ] } Friday, October 28, 2011
  26. metrics.librato.com Link Elements uri attribute describes resource rel attribute contains

    semantic markup link elements can be added/removed from representations Friday, October 28, 2011
  27. metrics.librato.com GLory of REST Single bookmarked URI Next states are

    discovered inline Series of representation exchanges transforms application state No URI templates/versioning Friday, October 28, 2011
  28. metrics.librato.com Have an API and build it first At least

    use CRUD Docs > Tests > Code Make it DRY Dogfood it Learn more about REST Friday, October 28, 2011
  29. metrics.librato.com Friday, October 28, 2011

  30. metrics.librato.com Friday, October 28, 2011

  31. metrics.librato.com Friday, October 28, 2011

  32. metrics.librato.com “be conservative in what you do, be liberal in

    what you accept from others” - Postel’s Law Friday, October 28, 2011