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

Wie soll man das denn nutzen? - Spring REST Docs

Gerrit Meier
September 30, 2016

Wie soll man das denn nutzen? - Spring REST Docs

REST API Dokumentation mit Spring REST Docs

Gerrit Meier

September 30, 2016
Tweet

More Decks by Gerrit Meier

Other Decks in Programming

Transcript

  1. Wie soll man das
    denn nutzen?
    Dokumentation von REST-Schnittstellen mit
    Spring REST Docs
    Gerrit [email protected] Saxony Day 2016

    View Slide

  2. „Eine schöne RESTful-API haben Sie da,
    wäre ja traurig, wenn die keiner nutzen 

    würde.“

    View Slide

  3. Problem:
    keine Dokumentation vorhanden

    View Slide

  4. Lösung:
    Dokumentation nachholen

    View Slide

  5. https://www.flickr.com/photos/whateverjamesinstitches/4623922729/

    View Slide

  6. Senior Consultant

    T-Systems on site services GmbH
    8 Jahre ‚professionell‘ Java
    JUG Ostfalen Co-Organisator
    Podcast
    meistermeier

    View Slide

  7. Gibt es da nicht schon etwas?

    View Slide

  8. Swagger

    View Slide

  9. View Slide

  10. @ApiOperation(nickname = "loginUser",

    value = "Logs user into the system", response = classOf[String], 

    httpMethod = "GET")

    @ApiResponses(Array(

    new ApiResponse(code = 400,
    message = "Invalid username and password combination")))

    def loginUser(

    @ApiParam(value = "The user name for login", required = true)

    username: String,

    @ApiParam(value = "The password for login in clear text", required = true) 

    password: String) = Action { 

    implicit request =>

    JsonResponse("logged in user session:" + System.currentTimeMillis())

    }

    View Slide


  11. @ApiOperation(nickname = "updateUser",

    value = "Updated user“,
    notes = "This can only be done by the logged in user.", httpMethod = "PUT")

    @ApiResponses(Array(

    new ApiResponse(code = 400, message = "Invalid username supplied"),

    new ApiResponse(code = 404, message = "User not found")))

    @ApiImplicitParams(Array(

    new ApiImplicitParam (name = "username", value = "name that need to be 

    updated", required = true, dataType = "String", paramType = "path"),

    new ApiImplicitParam(name = "body", value = "Updated user object",

    required = true, dataType = "models.User", paramType = "body")))

    def updateUser(username: String) = Action { implicit request =>

    request.body.asJson match {

    case Some(e) => {

    val user = Json.mapper.readValue(e.toString, classOf[User])

    userData.addUser(user)

    JsonResponse(user)

    }

    case None => JsonResponse(new value.ApiResponse(400, "Invalid input"))

    }

    }

    View Slide

  12. https://www.flickr.com/photos/endless_autumn/2820524593

    View Slide

  13. Das Problem von Dokumentation am 

    Code ist, dass sie veralten wird.

    View Slide

  14. @ApiResponses(

    value = {

    @ApiResponse(code = 200, message = "leaking resource available"),

    @ApiResponse(code = 404, message = "cannot find leaking resource"),

    }

    )

    public Status getLeakingInformation() {

    return new Status(200);

    }

    View Slide

  15. @ApiResponses(

    value = {

    @ApiResponse(code = 200, message = "leaking resource available"),

    @ApiResponse(code = 404, message = "cannot find leaking resource"),

    }

    )

    public Status getLeakingInformation() {

    return new Status(451);

    }

    View Slide

  16. View Slide

  17. http://martinfowler.com/articles/richardsonMaturityModel.html
    The Swamp of POX
    Resources
    HTTP Verbs
    Hypermedia Controls

    View Slide

  18. View Slide

  19. Spring REST Docs

    View Slide

  20. View Slide

  21. {

    "_links" : {

    "breweries" : {

    "href" : "http://localhost:8888/breweries"

    },

    "beers" : {

    "href" : "http://localhost:8888/beers"

    },

    "profile" : {

    "href" : "http://localhost:8888/profile"

    }

    }

    }
    $ curl 'http://localhost:8080/' -i

    View Slide

  22. @Test

    public void index() throws Exception {

    mockMvc.perform(RestDocumentationRequestBuilders.get(„/"))
    .andExpect(MockMvcResultMatchers.status().isOk())

    .andDo(
    document("index-page", links(

    linkWithRel("breweries").

    description("The <>“),

    linkWithRel("beers").description("The <>"),

    linkWithRel("profile").description("The ALPS profile for the service")

    ),
    responseFields(
    fieldWithPath("_links")

    .description("<> to other resources“)
    )

    ));

    }

    View Slide

  23. @Test

    public void index() throws Exception {

    mockMvc.perform(RestDocumentationRequestBuilders.get(„/"))
    .andExpect(MockMvcResultMatchers.status().isOk())

    .andDo(
    document("index-page", links(

    linkWithRel("breweries").

    description("The <>“),

    linkWithRel("beers").description("The <>"),

    linkWithRel("profile").description("The ALPS profile for the service")

    ),
    responseFields(
    fieldWithPath("_links")

    .description("<> to other resources“)
    )

    ));

    }

    View Slide

  24. @Test

    public void index() throws Exception {

    mockMvc.perform(RestDocumentationRequestBuilders.get(„/"))
    .andExpect(MockMvcResultMatchers.status().isOk())

    .andDo(
    document("index-page", links(

    linkWithRel("breweries").

    description("The <>“),

    linkWithRel("beers").description("The <>"),

    linkWithRel("profile").description("The ALPS profile for the service")

    ),
    responseFields(
    fieldWithPath("_links")

    .description("<> to other resources“)
    )

    ));

    }

    View Slide

  25. View Slide

  26. View Slide

  27. View Slide

  28. View Slide

  29. View Slide

  30. View Slide

  31. View Slide

  32. include::

    View Slide

  33. View Slide

  34. DEMO

    View Slide

  35. meistermeier
    https://projects.spring.io/spring-restdocs/
    https://github.com/spring-projects/spring-restdocs
    https://github.com/meistermeier/spring-rest-docs-sample

    View Slide