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

Documenting RESTful APIs

Andy Wilkinson
September 15, 2015

Documenting RESTful APIs

Slides of the talk on documenting RESTful APIs that I gave at SpringOne 2GX 2015

Andy Wilkinson

September 15, 2015
Tweet

More Decks by Andy Wilkinson

Other Decks in Programming

Transcript

  1. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ SPRINGONE2GX WASHINGTON, DC Documenting RESTful APIs Andy Wilkinson @ankinson
  2. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ How RESTful is your API? 2
  3. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ REST maturity model 3 Hyper
 media HTTP
 verbs Separate Resources XML-RPC SOAP RPC Level 0 Level 1 Level 2 Level 3 http://www.crummy.com/writing/speaking/2008-QCon/act3.html http://martinfowler.com/articles/richardsonMaturityModel.html
  4. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ How RESTful do you want it to be? 4
  5. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Making your API easy to document 5
  6. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Consistency 6 HTTP status codes HTTP verbs
  7. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Uniqueness 7 Use distinct relations on your links
  8. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 8 "_links" : { "self" : { "href" : "http://localhost:8080/" }, "notes" : { "href" : "http://localhost:8080/notes" }, "tags" : { "href" : "http://localhost:8080/tags" }
  9. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 9 "_links" : { "self" : { "href" : "http://localhost:8080/tags/3" }, "tagged-notes" : { "href" : "http://localhost:8080/tags/3/notes" } }
  10. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ What should you document? 10
  11. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Cross-cutting concerns 11 HTTP status codes HTTP verbs (PUT vs PATCH) Authentication and authorisation Rate limiting …
  12. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Resources 12 What do the represent? What input do they accept? What output do the produce?
  13. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Links 13 Where can you go? What will you find when you get there?
  14. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ What shouldn’t you document? 14
  15. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ URIs 15
  16. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ What does it look like when you get it wrong? 16 Learning from my mistakes
  17. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 17
  18. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ And when you get it right? 18
  19. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 19
  20. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ RESTful API documentation tools 20
  21. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Swagger 21 http://swagger.io springfox/springfox
  22. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ You get a lot for little effort 22
  23. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ But… 23
  24. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ It doesn’t support hypermedia 24 https://github.com/swagger-api/swagger-core/issues/97
  25. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ It’s URI centric 25
  26. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Always playing catch up – ResponseEntity 26 https://github.com/springfox/springfox/issues/532
  27. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Always playing catch up – HttpHeaders 27
  28. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ The writing experience is unpleasant 28 @RequestMapping(method=RequestMethod.POST, consumes=MediaType.APPLICATION_JSON_VALUE) @ApiOperation(value = "Create a new user", notes = "The name " + "of the user must be at least four characters in length.") @ApiResponses({ @ApiResponse(code=400, message="Bad request"), @ApiResponse(code=201, message="User created")}) @ResponseStatus(HttpStatus.CREATED) public HttpHeaders create(@RequestBody UserInput userInput) { … }
  29. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ It isn’t dry 29 @ApiResponses({ @ApiResponse(code=400, message="Bad request"), @ApiResponse(code=201, message="User created")}) @ResponseStatus(HttpStatus.CREATED) public HttpHeaders create(@RequestBody UserInput userInput) { … } @ExceptionHandler(IllegalArgumentException.class) private ResponseEntity<Void> handleIllegalArgumentException() { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); }
  30. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ It isn’t dry 30 @ApiResponses({ @ApiResponse(code=400, message="Bad request"), @ApiResponse(code=201, message="User created")}) @ResponseStatus(HttpStatus.CREATED) public HttpHeaders create(@RequestBody UserInput userInput) { … } @ExceptionHandler(IllegalArgumentException.class) private ResponseEntity<Void> handleIllegalArgumentException() { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); }
  31. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ It isn’t dry 31 @ApiResponses({ @ApiResponse(code=400, message="Bad request"), @ApiResponse(code=201, message="User created")}) @ResponseStatus(HttpStatus.CREATED) public HttpHeaders create(@RequestBody UserInput userInput) { … } @ExceptionHandler(IllegalArgumentException.class) private ResponseEntity<Void> handleIllegalArgumentException() { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); }
  32. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Swagger2Markup 32 Swagger2Markup/swagger2markup
  33. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ HAL and HAL Browser 33 http://stateless.co/hal_specification.html mikekelly/hal-browser
  34. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ HAL Browser demo 34
  35. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Spring REST Docs 35 spring-projects/spring-restdocs http://projects.spring.io/spring-restdocs
  36. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Write as much as possible in a format that’s designed for writing 36
  37. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Don’t use the implementation to provide the documentation 37
  38. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Provide some guarantees that the documentation is accurate TDD – Test-Driven Documentation 38
  39. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Asciidoctor Spring MVC Test Maven or Gradle 39 spring-projects/spring-restdocs
  40. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 40 @Test public void index() throws Exception { this.mockMvc.perform(get("/")) .andExpect(status().isOk()) .andExpect(jsonPath("_links.notes", is(notNullValue()))) .andExpect(jsonPath("_links.tags", is(notNullValue()))) .andDo(document("index")); } 5 4 3 2 1
  41. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 41 [source,bash] ---- $ curl 'http://localhost:8080/' -i ----
  42. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 42
  43. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 43 [source,http] ---- HTTP/1.1 200 OK Content-Type: application/hal+json { "_links" : { "tags" : { "href" : "http://localhost:8080/tags" }, "notes" : { "href" : "http://localhost:8080/notes" } }
  44. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 44
  45. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 45 this.mockMvc.perform(get("/")) .andExpect(status().isOk()) .andDo(document("index", links( linkWithRel("notes").description( "The <<resources-notes, Notes resource>>"), linkWithRel("tags").description( "The <<resources-tags, Tags resource>>") ), responseFields( fieldWithPath("_links").description( "<<resources-index-links,Links>> to other resources") ) )); 4 3 2 1 5 6
  46. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 46 |=== | Relation | Description | notes | The <<resources-notes,Notes resource>> | tags | The <<resources-tags,Tags resource>> |===
  47. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 47
  48. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 48 |=== |Path|Type|Description |_links |Object |<<resources-index-links,Links>> to other resources |===
  49. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 49
  50. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Spring REST Docs demo 50
  51. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software,

    Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Thank you 51 @ankinson wilkinsona [email protected]