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

Best of REST (JAX 2018)

Bc7aa56e8e004e4984e954e5e4cb2bc0?s=47 Tom Hombergs
April 24, 2018
220

Best of REST (JAX 2018)

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

April 24, 2018
Tweet

Transcript

  1. @TomHombergs 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("/books") .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. Contract First or Code First?

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

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

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

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

    0815, ... } ] } PUT /orders/4711 State Change
  31. // no content POST /orders/4711/complete Resource Action

  32. { "orderId": 4711, ... } POST /orderCompletions Action Resource GET

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

  36. Integration Testing a REST API

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

    DELETE /orders/4711
  38. Testing Interactions

  39. None
  40. None
  41. Adding an Identifier

  42. Removing an Identifier

  43. Changing Semantics of an Identifier

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

    Content-Type: application/json URI Versioning
  45. 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
  46. None
  47. None
  48. None
  49. OAuth 2.0

  50. OAuth 2.0

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

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

  53. None
  54. None
  55. None