Building Resilient API Clients (SLUG)

Building Resilient API Clients (SLUG)

An introduction to building API clients and servers which can evolve independently. This talk will cover connecting to an API without upfront knowledge about any implementation details such as URIs, HTTP "verbs" and content types but instead an understanding of the semantic meaning of what the API does. By leaning controls on the fly, we can allow a client and server to change independently over time.

D200a17dd269fd4001bacb11662dab4b?s=128

Kyle Fuller

June 25, 2015
Tweet

Transcript

  1. 2.
  2. 3.
  3. 5.
  4. 6.
  5. 7.
  6. 8.
  7. 9.
  8. 10.
  9. 20.

    /v1

  10. 21.

    /v2

  11. 24.
  12. 25.
  13. 30.
  14. 39.
  15. 40.
  16. 56.
  17. 58.

    HAL { "_embedded": { "choices": [ { "_links": { "self":

    { "self": "/questions/1/choices/1" } }, "choice": "Swift", "votes": 2048 } ] } }
  18. 59.
  19. 61.

    Siren { "actions": [ { "name": "create", "fields": [ {

    "name": "question", "type": "text", "title": "Question" }, { "name": "choices", "type": "array[text]", "title": "Choices" } ], "method": "POST", "type": "application/json", "href": "/questions" } ] }
  20. 64.
  21. 67.
  22. 74.

    func viewQuestion(question:Representor<HTTPTransition>) { println(question.attributes["question"]) if let choices = question.representors["choices"] {

    map(choices, viewChoice) } else { println("-> This question does not have any choices.") } if let delete = question.transitions["delete"] { // User may delete this question } }
  23. 75.

    func viewChoice(choice:Representor<HTTPTransition>) { let text = choice.attributes["choice"] let votes =

    choice.attributes["votes"] println('-> \(text) (\(votes))') if let vote = choice.transitions["vote"] { // User may vote on this choice } }
  24. 77.

    if let create = questions.transitions["create"] { // We may create

    a new question for attribute in create.attributes { // Creation takes `attribute.name` } } else { // Gracefully handle the lack of being able to create a question }
  25. 78.
  26. 82.
  27. 85.
  28. 86.
  29. 87.
  30. 88.
  31. 90.

    ## Questions Collection [/questions] ### List All Questions [GET] +

    Relation: questions + Response 200 (application/json) + Attributes (array[Question])
  32. 91.

    ### Create a New Question [POST] + Relation: create +

    Request (application/json) + Attributes + question (string, required) - The question + choices (array[string]) - A collection of choices. + Response 201 (application/json) + Attributes (Question)
  33. 92.

    ## Question [/questions/{question_id}] + Attributes + question: `Favourite programming language?`

    (string, required) + published_at: `2014-11-11T08:40:51.620Z` (string) - An ISO8601 date when the question was published + choices (array[Choice], required) - An array of Choice objects
  34. 95.

    ### Vote on a Choice [POST] This action allows you

    to vote on a question's choice. + Relation: vote + Response 201
  35. 99.