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

Best of REST (JUG)

Best of REST (JUG)

A tour through some of the major decisions we have to make when implementing a HTTP API (or even a REST API).

Bc7aa56e8e004e4984e954e5e4cb2bc0?s=128

Tom Hombergs

March 13, 2018
Tweet

More Decks by Tom Hombergs

Other Decks in Technology

Transcript

  1. Tom Hombergs Best of REST

  2. None
  3. None
  4. The Swamp of Plain Old XML POST / Client Server

    <?xml version="1.0"?> <request> <action>createBook</action> <payload> <title>…</title> </payload> </request>
  5. Resources Client Server POST /books POST /books/42?action=update {"title": "Hitchhiker's Guide

    to The Galaxy"} { "action": "create", "payload": { "title": "Hitchhiker's Guide to The Galaxy" } }
  6. HTTP Verbs Client Server POST /books PUT /books/42 {"title": "Hitchhiker's

    Guide to The Galaxy"} {"title": "Hitchhiker's Guide to The Galaxy"}
  7. Hypermedia

  8. Links and Relations { "_links" :{ "list": { "href": "/books"

    } // more links ... } } GET /
  9. Links and Relations { "bookList": [{ "title": "...", "_links": {

    "self": { "href": "/books/42" } } } } GET /books
  10. Links and Relations

  11. @SpringBootApplication @EnableHypermediaSupport(type = HypermediaType.HAL) public class MyApplication{ public static void

    main(String[] args) { SpringApplication.run(MyApplication.class, args); } } Hypermedia with Spring Boot
  12. @GetMapping(path = "books/{id}") public ResponseEntity getBook(@PathVariable Long id) { Book

    book = bookRepository.findOne(id); BookResource result = bookAssembler.toResource(book); return new ResponseEntity(result, HttpStatus.OK); } Hypermedia with Spring Boot
  13. Hypermedia?

  14. None
  15. Good API Docs

  16. None
  17. None
  18. None
  19. Generating Docs with Spring Rest Docs document("books/create", links(halLinks(), linkWithRel("self") .description("Link

    to the created book."), requestFields( fields.withPath("title") .description("The title of the book.")));
  20. Generating Docs with Spring Rest Docs document("books/create", links(halLinks(), linkWithRel("self") .description("Link

    to the created book."), requestFields( fields.withPath("title") .description("The title of the book.")));
  21. @Test public void createProjectSuccessfully() throws Exception { ProjectResource project =

    projectResource().validProjectResource(); mvc().perform(post("/projects") .content(toJsonWithoutLinks(project)) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) .andExpect(containsResource(ProjectResource.class)) .andDo(document(...)); } Generating Docs from Tests
  22. Generating Docs from Tests

  23. REST Controller Test with Spring Boot @RunWith(SpringRunner.class) @WebMvcTest(controllers=MyController.class) public class

    MyControllerTest{ // test methods ... }
  24. Contract First or Code First?

  25. None
  26. POST /orders PUT /orders/4711 PUT /orders/4711 Fat Resource { "orderId":

    4711, "orderItems": [ { "articleId": 0815, ... } ] }
  27. { "orderId": 4711, "orderItems": [ { "articleId": 0815, ... }

    ] } POST /orders POST /orders/4711/items PUT /orders/4711/items Nested Resource DELETE /orders/4711/items
  28. { "orderId": 4711, "orderItemCount": 2 } GET /orders/4711?view=summary Resource Views

    GET /orders/4711/views/summary GET /orders/4711 Accepts: application/vnd+adesso.orderSummary+json
  29. None
  30. None
  31. { "orderId": 4711, "status": "COMPLETE" , "orderItems": [ { "articleId":

    0815, ... } ] } PUT /orders/4711 State Change
  32. { "orderId": 4711, "orderItems": [ { "articleId": 0815, ... }

    ] } POST /orders/4711/complete Resource Action
  33. { "orderId": 4711, ... } POST /orderCompletions Action Resource GET

    /orderCompletions
  34. None
  35. None
  36. Testing an API

  37. Integration Testing a REST API

  38. Testing Endpoints on the Provider Side GET /orders/4711 POST /orders

    DELETE /orders/4711
  39. Testing Interactions

  40. None
  41. None
  42. Adding an Identifier

  43. Removing an Identifier

  44. Changing Semantics of an Identifier

  45. GET /orders GET /v1/orders GET /v2/orders Content-Type: application/json Content-Type: application/json

    Content-Type: application/json URI Versioning
  46. GET /orders Accept: application/vnd+adesso.orders+json Header Versioning GET /orders Accept: application/vnd+adesso.orders+json;v=1

    GET /orders Accept: application/vnd+adesso.orders+json;v=2
  47. None
  48. None
  49. None
  50. OAuth 2.0

  51. OAuth 2.0

  52. JWT create signedtoken Client Server login withusername/ password returntoken send

    token witheach request check token signature read user informationfromtoken returnresponse
  53. JWT

  54. None
  55. None
  56. None