Test-Driven Documentation for your REST(ful) service

Test-Driven Documentation for your REST(ful) service

Building RESTful APIs in Java? Getting tired of the annotation bloat forced upon you by your API specification framework which haunts your RESTful service controllers and model objects? Finding yourself in the situation where your code isn’t always in synch with your specification or vice versa?
RAML and Swagger / OpenAPI are great specifications with powerful and shiny tooling, but they do also really have their downsides when it comes to messing with our code.

Fear not! There are other alternatives worth investigating. In this talk, we’ll take a look at how we recently build, designed and documented a public REST API by doing Test Driven Documentation with some help of AsciiDoc and Spring (Auto) REST Docs.

2c3ad1c6891845c582e0171e2e1753b1?s=128

Jeroen Reijn

April 12, 2018
Tweet

Transcript

  1. Test-Driven Documentation for your RESTful service by Jeroen Reijn

  2. JEROEN REIJN Software Architect at Luminis /Amsterdam • Focus on

    productivity and Developer Experience • Been building APIs for the Web since 2010 • Writes most of his code in Java • Tweets @jreijn
  3. Let’s talk about Web APIs

  4. source: https://www.programmableweb.com/

  5. Streaming 1% RPC 10% REST 89% REST RPC Streaming GraphQL

    source: https://www.programmableweb.com/
  6. REST

  7. Source: http://geek-and-poke.com/geekandpoke/2013/6/14/insulting-made-easy

  8. Richardson Maturity Model Source: https://www.martinfowler.com/articles/richardsonMaturityModel.html HATEOAS (Hypermedia as the Engine

    of Application State)
  9. REST • Uniform interface • Resources • URIs • Representations

    • Hypermedia
  10. Hypermedia • Links in resource representations • State navigations discoverable

  11. Hypertext link specifications • HAL • JSON-LD • JSON API

    • Collection+JSON • Siren
  12. Hypertext link specifications { "_links" : { "self" : {

    "href" : "http://localhost:8080/" }, "planets" : { "href" : "http://localhost:8080/planets" }, "people" : { "href" : "http://localhost:8080/people" } } }
  13. Building an API Design Build Document

  14. Let’s talk about API design

  15. Specification driven vs Code driven

  16. Specification Driven Design Contract Driven Design a.k.a

  17. Manual spec

  18. API design

  19. RAML • RESTful API Modelling Language (RAML) • Based on

    YAML file format • Powerful designer api with auto completion • Code generation for Java • No native support for HATEOAS
  20. None
  21. API Blueprint / Apiary • Markdown flavoured syntax • Powerful

    designer UI • Documentation while designing • Java code generator support is *very* minimal
  22. None
  23. Postman • Postman client is great for testing APIs •

    Supports designing & documenting APIs • Has support for Api Mocks • Enables fast prototyping of APIs • Tools for different phases in the API lifecycle
  24. None
  25. Open API • Widely adopted community-driven specification for REST APIs

    • YAML and JSON based format • Programming language-agnostic interface • Allows both code first and contract first approaches to API design • Evolving specification (version 3.0 released in the summer of 2017)
  26. Swagger • Tools around the OpenAPI specification • Swagger editor

    • Swagger-UI • Swagger Codegen (server and client libs and many languages) • Swagger Inspector
  27. None
  28. None
  29. Swagger Codegen /** * Unique identifier representing a specific planet.

    * @return id **/ @ApiModelProperty(value = "Unique identifier representing a specific planet.") public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Planet name(String name) { this.name = name; return this; }
  30. Retrospect • API Design tools and platform are getting really

    powerful • OpenAPI seems to be the most widely adopted api spec • Generating code from your API specification is up to you
  31. Code Driven Design

  32. None
  33. “ An API is only as good 
 as its

    documentation! ”
  34. Let’s talk about API documentation

  35. None
  36. Manual documentation

  37. Documentation based on specs HTML / PDF

  38. Docs based on code @GetMapping(value = "/films/{id}") ResponseEntity<Film> getFilmById(@PathVariable(“id") String

    id);
  39. Docs based on code @ApiOperation(value = "", nickname = “getfilmbyid",

    notes = "Get a specific film by id.", response = Film.class, authorizations = { @Authorization(value = "apikeyQuery") }, tags = {}) @ApiResponses(value = { @ApiResponse(code = 200, message = "A film.", response = Film.class)}) @GetMapping(value = “/films/{id}") ResponseEntity<Film> getFilmById(@ApiParam(value = "Id of the film.", required = true) @PathVariable("id") String id);
  40. None
  41. Swagger drawbacks • Hypermedia support not ‘final’ • Documentation is

    done through several annotations which are added in your implementation classes • API Implementation code overtime, gets overwhelmed with annotations • Documentation is URI centric • Documentation and API could become out-of-sync overtime
  42. “ API documentation needs to be more then just endpoints

    and resources ”
  43. Spring REST Docs “Document RESTful services by combining 
 hand-written

    documentation with 
 auto-generated snippets 
 produced with Spring MVC Test.”
  44. Spring REST Docs • Documentation is built from tests •

    Supports hypermedia (HATEOAS) APIs • Immediate reaction to API changes • Keeps your code clean • Produces AsciiDoc snippets
  45. Basic Spring MVC Test @Test public void testGetAllPlanets() throws Exception

    { mockMvc.perform(get("/planets").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.length()",is(2))); }
  46. With Spring REST Doc @Test public void testGetAllPlanets() throws Exception

    { mockMvc.perform(get("/planets").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.length()",is(2))) .andDo(document("planets/get")); }
  47. AsciiDoc snippets |=== |Path|Type|Description |`id` |`Number` |The id of the

    planet |`name` |`String` |The name of the planet |`diameter` |`Number` |The diameter of the planet |===
  48. AsciiDoc Plain-text writing format. AsciiDoc documents can be translated into

    various formats, including HTML, DocBook, PDF and ePub. = Hello, DevCon! Jeroen Reijn <jeroen.reijn@luminis.eu> An introduction to documenting Hypermedia APIs with https://projects.spring.io/spring-restdocs/[Spring REST Docs]. == First Section * item 1 * item 2
  49. Generating documentation Test Generated snippets AsciiDoctor plugin Hand-written docs Code

    Document
  50. Let’s build an API!

  51. Spring Auto REST Docs • Extension for Spring REST Docs

    • Response field documentation generated by means of introspection • Partial support for documenting Hypermedia ‘links’ out of the box • DRY - Uses JavaDoc for generating documentation
  52. Spring REST Docs advantages • Ability to focus on domain

    model rather than URI’s • ‘Guarantees’ that API documentation and implementation code are in-sync • Forces you to update documentation for any implementation changes • Ability to document with different payloads and explain different test scenarios • Ability to document remote APIs (with WebTestClient)
  53. In retrospect • Documenting Hypermedia APIs is getting easier •

    Validating APIs against their documentation is still ‘hard’ • Spring REST Docs can help documenting and validating the API • Good documentation is key to working with an API
  54. Those who stand for nothing, fall for anything - Alexander

    Hamilton ? Thank you Questions? is powered by Don’t forget to vote! Sources available @ https://github.com/jreijn/devcon-rest-tdd-demo