Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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" }

Slide 9

Slide 9 text

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" } }

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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 …

Slide 12

Slide 12 text

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?

Slide 13

Slide 13 text

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?

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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) { … }

Slide 29

Slide 29 text

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 handleIllegalArgumentException() { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); }

Slide 30

Slide 30 text

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 handleIllegalArgumentException() { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); }

Slide 31

Slide 31 text

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 handleIllegalArgumentException() { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); }

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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 ----

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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" } }

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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 <>"), linkWithRel("tags").description( "The <>") ), responseFields( fieldWithPath("_links").description( "<> to other resources") ) )); 4 3 2 1 5 6

Slide 46

Slide 46 text

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 <> | tags | The <> |===

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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 |<> to other resources |===

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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 awilkinson@pivotal.io