Embracing Change with REST

Embracing Change with REST

People are fairly good at short-term design, and usually awful at long-term design". Let's learn how we can promote longevity and independent evolution of your API by decoupling and encapsulation using the engine of application state in REST.

Resources to learn more:

- Solving Fizz Buzz with Hypermedia: http://smizell.com/weblog/2014/solving-fizzbuzz-with-hypermedia
- REST APIs must be hypertext driven - http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
- Representor in Swift - https://github.com/the-hypermedia-project/representor-swift
- Roy Fielding on Versioning - http://www.infoq.com/articles/roy-fielding-on-versioning
- Polls API - Implementation of a RESTful API - https://github.com/apiaryio/polls-api
- rivr-rest: Python framework for building RESTful APIs - http://github.com/rivrproject/rivr-rest

D200a17dd269fd4001bacb11662dab4b?s=128

Kyle Fuller

March 22, 2015
Tweet

Transcript

  1. Embracing Change with REST Kyle Fuller

  2. Representational State Transfer

  3. What is REST?

  4. Roy Fielding

  5. “Anticipating change is one of the central themes of REST”

  6. "Move fast and break things" Mark Zuckerberg, Facebook

  7. None
  8. None
  9. "Each version will remain for at least 2 years from

    release." Facebook
  10. Move Fast, Break Nothing

  11. REST is not... 4 CRUD 4 Pretty URLs 4 JSON

    4 HTTP Verbs 4 Routing
  12. It’s not about exposing your database

  13. But... we design apps this way

  14. Actually, We Don't

  15. We design implementations this way

  16. Todo 4 id 4 title 4 status

  17. Designing API by exposing implementation details

  18. Designing API by exposing implementation details

  19. We could design via states

  20. None
  21. How do we Transfer State from Server to Client?

  22. We transfer Representations of State

  23. Hence Representational State Transfer

  24. How do we transfer state transitions?

  25. HATEOAS

  26. None
  27. HATEOAS Hypermedia as the Engine of Application State

  28. Relations

  29. Transitions

  30. "HATEOAS" is a REST constraint.

  31. Not an option. Not an ideal. Hypermedia is a constraint.

  32. As in, you either do it or you aren’t doing

    REST.
  33. GET http://polls.com/ <html> <body> <h1>Things you can do</h1> <ul> <li><a

    href="/questions/new" rel="create">Make a new question</a></li> </ul> </body> </html>
  34. GET http://polls.com/ <html> <body> <h1>Things you can do</h1> <ul> <li><a

    href="/polls/new" rel="create">Make a new question</a></li> </ul> </body> </html>
  35. Creating a question the bad way 4 Construct a 'new

    question' URL 4 Submit a form given our pre-existing knowledge of how it may look 4 Visit the page (it may or may not work)
  36. with hypermedia 4 We’re offered to create a question 4

    Fill in the form it gives you 4 Submit the form
  37. Exactly how you browse the web

  38. Clients can have the same benefits by doing this too

  39. Polls

  40. Questions 4 create 4 list

  41. Question 4 delete 4 choices

  42. Choice 4 vote

  43. One Does Not Simply Use JSON

  44. Hypermedia Formats 4 HAL (application/hal+json) 4 Siren (application/vnd.siren+json)

  45. Siren Link { "links": [ { "rel": ["next"], "href": "/questions?page=2"

    } ] }
  46. Siren Link { "links": [ { "rel": ["choice"], "href": "/questions/1/choices/1"

    } ] }
  47. Siren Link { "entities": [ { "links" { { "rel":

    ["self"], "href": "/questions/1/choices/1" } }, "rel": ["choices"], "properties": {"choice": "Swift", "votes": 22} } ] }
  48. Siren Link { "entities": [ { "rel": ["choices"], "properties": {"choice":

    "Swift", "votes": 22}, "actions": [ { "href": "/questions/1/choices/1", "name": "vote", "method": "POST" } ] } ] }
  49. Siren Action { "actions": { "create": { "href": "/questions", "method":

    "POST", "fields": [ { "name": "question" }, { "name": "choices" } ] } } }
  50. Siren Action { "actions": { "create": { "href": "/questions", "method":

    "POST", "fields": [ { "name": "question" }, { "name": "choices" } ], "type": "application/x-www-form-urlencoded" } } }
  51. Siren Action { "actions": { "create": { "href": "/questions", "method":

    "POST", "fields": [ { "name": "question" }, { "name": "choices" } ], "type": "application/json" } } }
  52. { "actions": { "create": { "href": "/questions", "method": "POST", "fields":

    [ { "name": "question" }, { "name": "choices" } ], "type": "application/json" } } }
  53. Ability to change implementation details

  54. Ability to change implementation details 4 Change URIs of resources

    (/polls/{id} -> / questions/{slug})
  55. Ability to change implementation details 4 Change URIs of resources

    (/polls/{id} -> / questions/{slug}) 4 Change HTTP methods (PUT -> PATCH)
  56. Ability to change implementation details 4 Change URIs of resources

    (/polls/{id} -> / questions/{slug}) 4 Change HTTP methods (PUT -> PATCH) 4 Change the content-type
  57. Ability to change implementation details 4 Change URIs of resources

    (/polls/{id} -> / questions/{slug}) 4 Change HTTP methods (PUT -> PATCH) 4 Change the content-type 4 Change fields used in forms
  58. Teach Clients Semantic meaning of the Domain

  59. Don’t hard-code implementation details

  60. Demo

  61. Representor https://github.com/the-hypermedia-project/representor-swift

  62. Using a transition if let transition = representor.transitions["create"] { }

  63. Using a transition if let transition = representor.transitions["create"] { }

    else { // Gracefully handle the lack of this transition }
  64. Using a transition if let transition = representor.transitions["create"] { transition.attributes

    }
  65. Using a transition if let transition = representor.transitions["create"] { transition.method

    transition.uri transition.suggestedContentType }
  66. Performing a Transition request(transition, attributes:[ "question": "Favourite programming language?", "choices":

    [ "Swift", "Python", ] ])
  67. REST

  68. Resources 4 REST APIs must be hypertext driven 4 Representor

    4 Roy Fielding on Versioning 4 Polls API 4 rivr rest 4 Solving Fizz Buzz with Hypermedia
  69. Kyle Fuller ! fuller.li/slides ! kyle@fuller.li