58
Introducing Spring Auto REST Docs Florian Benz @flbenz

Introducing Spring Auto REST Docs - Spring IO 2017

Embed Size (px)

Citation preview

Page 1: Introducing Spring Auto REST Docs - Spring IO 2017

IntroducingSpring Auto REST Docs

Florian Benz@flbenz

Page 2: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

DR REST DOCS

OR: HOW I LEARNED TO STOP WORRYING AND LOVE DOCUMENTATION

Page 3: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Florian Benz

Software Engineer

@flbenz

Page 4: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Scalable Capital

• Europe’s fastest growing Digital Wealth Manager

• Authorized financial institute in Germany and the UK

• From scratch with Spring Boot

• Joined effort with Juraj Misur @juraj_misur

Page 5: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Spring Auto REST Docs

Scalable Capital founded

Dec 2014

Proof of concept

Jul 2015

First article

Nov 2015

Page 6: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Spring Auto REST Docs

Open source&

First release

Dec 2016

DZone article

Jan 2017

Two releases with fixes and

features

Feb & Mar 2017

Page 7: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Our Story

Page 8: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Manual Documentation

DocumentationCode

Page 9: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

A single big document

Page 10: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Specification-Driven Documentation

DocumentationCode

Specification

Page 11: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

RAML Specification/weather:

get:

queryParameters:

city:

description: Name of a city in the given country.

responses:

200:

body:

application/json:

schema: |

{ "$schema": "http://json-schema.org/schema",

"type": "object",

"description": "Weather information",

"properties": {

"temperature": { "type": "number" }

}

}

Page 12: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Swagger / OpenAPI@GetMapping("weatherParam")@ApiOperation("weather")@ApiImplicitParams({ @ApiImplicitParam(name = "country", value = "Country code", required = true, dataType = "string", paramType = "query"), @ApiImplicitParam(name = "city", value = "City", required = true, dataType = "string", paramType = "query")})@ApiResponses({ @ApiResponse(code = 200, message = "Success", response = WeatherResponse.class)})public WeatherResponse weatherParam(@RequestParam @IsoCountryCode String country, @RequestParam String city) { return new WeatherResponse(20);}

Page 13: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Swagger / OpenAPI

Page 14: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Postman

Page 15: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Test-Driven Documentation

DocumentationCode

Tests

Page 16: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Spring REST Docs

Generatedsnippets

Tests

Hand-written documentation

Documentation

Page 17: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Spring MVC Test@Testpublic void shouldReturnWeatherForBarcelona() throws Exception { mockMvc.perform( post("/weather") .contentType(MediaType.APPLICATION_JSON) .content("{\"country\": \"ES\", \"city\": \"Barcelona\"}") ) .andExpect(status().isOk()) .andExpect(jsonPath("$.temperature", is(20)));}

Page 18: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Spring REST Docs@Testpublic void shouldReturnWeatherForBarcelona() throws Exception { mockMvc.perform( post("/weather") .contentType(MediaType.APPLICATION_JSON) .content("{\"country\": \"ES\", \"city\": \"Barcelona\"}") ) .andExpect(status().isOk()) .andExpect(jsonPath("$.temperature", is(20))); .andDo(document("weather", requestFields( fieldWithPath("country").description("Country code"), fieldWithPath("city").description("City name"))));}

Page 19: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Generated snippet|===|Path|Type|Optional|Description

|country|String|false|Country Code.

|city|false|true|City name.

|===

Page 20: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

AsciiDoc[[resources-weather]]= Weather for your city

`POST /weather`

Up-to-date temperature for the given city

== Response structure

include::{snippets}/weather/response-fields.adoc[]

== Example request/response

include::{snippets}/weather/curl-request.adoc[]include::{snippets}/weather/http-response.adoc[]

Page 21: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Spring REST Docs

Page 22: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Spring REST Docs

Page 23: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Spring REST Docs

Controller

POJO

Response Entity

Jackson

HTTP response Documented

Page 24: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

ExtendingSpring REST Docs

Page 25: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Motivation

.andDo(document("weather", requestFields( fieldWithPath("country").description("Country code"), fieldWithPath("city").description("Name of a city"))));

We are lazy

Page 26: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Proof of concept

Page 27: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Spring Auto REST Docs

Controller

POJO

Response Entity

Jackson

HTTP response

Javadoc

Introspection

Page 28: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Spring REST Docs@Testpublic void shouldReturnWeatherForBarcelona() throws Exception { mockMvc.perform( post("/weather") .contentType(MediaType.APPLICATION_JSON) .content("{\"country\": \"ES\", \"city\": \"Barcelona\"}") ) .andExpect(status().isOk()) .andExpect(jsonPath("$.temperature", is(20))); .andDo(document("weather", requestFields( fieldWithPath("country").optional().description("Country code"), fieldWithPath("city").optional().description("City name"))));}

Page 29: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Spring Auto REST Docs@Testpublic void shouldReturnWeatherForBarcelona() throws Exception { mockMvc.perform( post("/weather") .contentType(MediaType.APPLICATION_JSON) .content("{\"country\": \"ES\", \"city\": \"Barcelona\"}") ) .andExpect(status().isOk()) .andExpect(jsonPath("$.temperature", is(20))); .andDo(document("weather"));}

Page 30: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Javadocclass WeatherRequest { /** * Country code. */ private String country; /** * City name. */ private String city;}

Path Type Optional Description

country String true Country code.

city String true City name.

Page 31: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Constraintsclass WeatherRequest { /** * Country code, e.g. ES, DE, US. */ @NotNull @IsoCountryCode private String country; /** * City name. */ @NotBlank private String city;}

Path Type Optional Description

country String false Country code.Must be an ISO country code.

city String false City name.

Page 32: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Constraints

package.OneOf.description=Must be one of ${value}package.IsoCountryCode.description=Must be an ISO country code

ConstraintDesciptions.properties

Page 33: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Constraintsclass WeatherRequest { /** * Country code, e.g. ES, DE, US. */ @NotNull @IsoCountryCode(groups = Iso.class) @CountryName(groups = Plain.class) private String country;}

Path Type Optional Description

country String false Country code.ISO: Must be an ISO country code.Plain: Must be a country name.

Page 34: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Enumsclass WeatherRequest { /** * Country code, e.g. ES, DE, US. */ @NotNull private Country country; /** * City name. */ @NotBlank private String city;}

Path Type Optional Description

country String false Country code.Must be one of [DE, ES, FR, PT, US].

city String false City name.

Page 35: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Original: hand-written

2.8. WeatherPOST /weather

Up-to-date weather data for cities around the globe.

[[resources-weather]]= Weather for your city

`POST /weather`

Up-to-date temperature for the given city

Page 36: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Extension: Javadoc on method/*** Up-to-date weather data for cities around the globe.*/@PostMapping("weather")public WeatherResponse weather( @RequestBody @Valid WeatherRequest weatherRequest) { return new WeatherResponse(20);}

2.8. WeatherPOST /weather

Up-to-date weather data for cities around the globe.

Page 37: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Original: Path Parameters

.andDo(document("weather", pathParameters( parameterWithName("country").description("Country code"), parameterWithName("city").description("City name"))));

Page 38: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Extension: Path Parameters/*** Up-to-date weather data for cities around the globe.** @param country Country code.* @param city City name.*/@GetMapping("weather/{country}/{city}")public WeatherResponse weatherPath( @PathVariable @IsoCountryCode String country, @PathVariable String city) { return new WeatherResponse(20);}

Page 39: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Path Parameters

Page 40: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Path Parameters

Page 41: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Original: Query Parameters

.andDo(document("weather", requestParameters( parameterWithName("country").description("Country code"), parameterWithName("city").description("City name"))));

Page 42: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Extension: Query Parameters/** * Up-to-date weather data for cities around the globe.** @param country Country code.* @param city City name.*/@GetMapping("weatherParam")public WeatherResponse weatherParam( @RequestParam @IsoCountryCode String country, @RequestParam String city) { return new WeatherResponse(20);}

Page 43: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Query Parameters

Page 44: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Query Parameters

Page 45: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Section Snippet[[resources-weather]]=== Weather for your city

`POST /weather`

Up-to-date temperature for the given city

===== Request structure

include::{snippets}/weather/request-fields.adoc[]

===== Response structure

include::{snippets}/weather/response-fields.adoc[]

===== Example request/response

include::{snippets}/weather/curl-request.adoc[]include::{snippets}/weather/http-response.adoc[]

include::{snippets}/weather/section.adoc[]

Documentation path

Spring MVC Controller

Javadoc

Method name

Page 46: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Authorization snippet

Page 47: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Content Modifiers

[ 1, 2, 3, 4, 5]

[ 1, 2, 3]

array shortener

Page 48: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Content Modifiers

%PDF-1.5%����12 0 obj<</Length 3654 /Filter /FlateDecode>>

<binary>

binary replacement

Page 49: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Benefits

Less to write

Code review Maintainability

Happier developers

DRY

Accurate

Page 50: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Sounds good!

Issues?

Page 51: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Issues

Page 52: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Issues

Page 53: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Issues

Page 54: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

It’s an extension

Authorization snippet

Javadoc/introspection snippets

Content modifiers

Page 55: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Spring Auto REST Docsat Scalable Capital

Page 56: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Spring Auto REST Docsat Scalable Capital

Page 57: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Thank you

Page 58: Introducing Spring Auto REST Docs - Spring IO 2017

@spring_io#springio17

Q&A

@flbenz