Inleiding tot Spring REST Docs

REST Top

Ik heb zojuist het nieuwe aangekondigd Leer de lente natuurlijk, gericht op de basisprincipes van Spring 5 en Spring Boot 2:

>> BEKIJK DE CURSUS

1. Overzicht

Spring REST Docs genereert documentatie voor RESTful-services die zowel nauwkeurig als leesbaar is. Het combineert handgeschreven documentatie met automatisch gegenereerde documentfragmenten die zijn geproduceerd met Spring-tests.

2. Voordelen

Een belangrijke filosofie achter het project is het gebruik van tests om de documentatie te produceren. Dit zorgt ervoor dat de documentatie die altijd wordt gegenereerd nauwkeurig overeenkomt met het daadwerkelijke gedrag van de API. Bovendien is de uitvoer klaar om te worden verwerkt door Asciidoctor, een publicatie-toolchain gecentreerd rond de AsciiDoc-syntaxis. Dit is dezelfde tool die wordt gebruikt om de documentatie van het Spring Framework te genereren.

Deze benaderingen verminderen de beperkingen die door andere kaders worden opgelegd. Spring REST Docs produceert documentatie die nauwkeurig, beknopt en goed gestructureerd is. Deze documentatie stelt de webservice-gebruikers vervolgens in staat om met een minimum aan gedoe de informatie te krijgen die ze nodig hebben.

De tool heeft nog enkele andere voordelen, zoals:

  • curl- en http-verzoekfragmenten worden gegenereerd
  • eenvoudig te verpakken documentatie in jar-bestand van projecten
  • eenvoudig om extra informatie aan de fragmenten toe te voegen
  • ondersteunt zowel JSON als XML

De tests die de fragmenten produceren, kunnen worden geschreven met behulp van Spring MVC Test-ondersteuning, Spring Webflux's WebTestClient of REST-Assured.

In onze voorbeelden gaan we Spring MVC-tests gebruiken, maar het gebruik van de andere frameworks lijkt erg op elkaar.

3. Afhankelijkheden

De ideale manier om aan de slag te gaan met Spring REST Docs in een project, is door een afhankelijkheidsbeheersysteem te gebruiken. Hier gebruiken we Maven als build-tool, dus de onderstaande afhankelijkheid kan worden gekopieerd en in uw POM worden geplakt:

 org.springframework.restdocs spring-restdocs-mockmvc 2.0.4.RELEASE 

U kunt hier ook Maven Central controleren voor een nieuwe versie van de afhankelijkheid.

In ons voorbeeld hebben we de spring-restdocs-mockmvc afhankelijkheid omdat we de Spring MVC-testondersteuning gebruiken om onze tests te maken.

Als we tests willen schrijven met WebTestClient of REST Assured, hebben we de afhankelijkheden spring-restdocs-webtestclient en spring-restdocs-restassured nodig.

4. Configuratie

Zoals vermeld, zullen we het Spring MVC Test-framework gebruiken om verzoeken te doen aan de REST-services die moeten worden gedocumenteerd. Het uitvoeren van de test levert documentatiefragmenten op voor het verzoek en het resulterende antwoord.

We kunnen de bibliotheek gebruiken met zowel JUnit 4- als JUnit 5-tests. Laten we eens kijken naar de configuratie die voor elk nodig is.

4.1. JUnit 4-configuratie

De allereerste stap bij het genereren van documentatiefragmenten voor JUnit 4-tests is om openbaar verklaren JUnitRestDocumentation veld dat is geannoteerd als een JUnit @Regel.

De JUnitRestDocumentation regel is geconfigureerd met de uitvoermap waarin de gegenereerde fragmenten moeten worden opgeslagen. Deze directory kan bijvoorbeeld de build-out directory van Maven zijn:

@ Regel openbare JUnitRestDocumentation restDocumentation = nieuwe JUnitRestDocumentation ("doel / gegenereerde-fragmenten");

Vervolgens stellen we het MockMvc context zodat het wordt geconfigureerd om documentatie te produceren:

@Autowired privé WebApplicationContext-context; privé MockMvc mockMvc; @Before public void setUp () {this.mockMvc = MockMvcBuilders.webAppContextSetup (this.context) .apply (documentationConfiguration (this.restDocumentation)) .build (); }

De MockMvc object is geconfigureerd met een MockMvcRestDocumentationConfigurer. Een instantie van deze klasse kan worden verkregen uit de static documentatieConfiguratie () methode op org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.

4.2. JUnit 5-configuratie

Om met een JUnit 5-test te werken, moeten we de test uitbreiden met de RestDocumentationExtension klasse:

@ExtendWith ({RestDocumentationExtension.class, SpringExtension.class}) @SpringBootTest openbare klasse ApiDocumentationJUnit5IntegrationTest {// ...}

Deze klasse wordt automatisch geconfigureerd met een / target / generated-snippets uitvoermap bij gebruik van Maven, of / build / Genereer-fragmenten voor Gradle.

Vervolgens moeten we het MockMvc bijvoorbeeld in een @BeforeEach methode:

@BeforeEach openbare void setUp (WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {this.mockMvc = MockMvcBuilders.webAppContextSetup (webApplicationContext) .apply (documentationConfiguration (restDocumentation)). Build (); }

Als we JUnit niet gebruiken voor de tests, moeten we de ManualRestDocumentation klasse.

5. RUSTIGE service

Laten we een CRUD RESTful-service maken die we kunnen documenteren:

@RestController @RequestMapping ("/ crud") openbare klasse CRUDController {@GetMapping openbare lijst gelezen (@RequestBody CrudInput crudInput) {List returnList = nieuwe ArrayList (); returnList.add (crudInput); terugkeer returnList; } @ResponseStatus (HttpStatus.CREATED) @PostMapping openbare HttpHeaders opslaan (@RequestBody CrudInput crudInput) {HttpHeaders httpHeaders = nieuwe HttpHeaders (); httpHeaders.setLocation (linkTo (CRUDController.class) .slash (crudInput.getTitle ()). toUri ()); retourneer httpHeaders; } @DeleteMapping ("/ {id}") openbare ongeldige verwijdering (@PathVariable ("id") lange id) {// delete}}

Laten we dan ook een IndexController die een pagina retourneert met een link naar de CRUDController basis eindpunt:

@RestController @RequestMapping ("/") openbare klasse IndexController {statische klasse CustomRepresentationModel breidt RepresentationModel uit {openbaar CustomRepresentationModel (Link initialLink) {super (initialLink); }} @GetMapping openbare CustomRepresentationModel index () {retourneer nieuw CustomRepresentationModel (linkTo (CRUDController.class) .withRel ("crud")); }}

6. JUnit-tests

Terug in de tests kunnen we de MockMvc bijvoorbeeld om onze diensten te bellen en het verzoek en antwoord te documenteren.

Eerste, om ervoor te zorgen dat elk MockMvc oproep wordt automatisch gedocumenteerd zonder enige verdere configuratie kunnen we de doe altijd() methode:

this.mockMvc = MockMvcBuilders // ... .alwaysDo (document ("{method-name}", preprocessRequest (prettyPrint ()), preprocessResponse (prettyPrint ()))) .build ();

Deze opzet zorgt ervoor dat alles voor elk MockMvc call, worden de standaardfragmenten gemaakt in een map met de naam van de testmethode. Ook het toepassen van de prettyPrint () pre-processor geeft de fragmenten op een gemakkelijker leesbare manier weer.

Laten we doorgaan met het aanpassen van enkele van onze oproepen.

Om onze indexpagina te documenteren die een link bevat, kunnen we de static gebruiken links () methode:

@Test public void indexExample () genereert Uitzondering {this.mockMvc.perform (get ("/")). AndExpect (status (). IsOk ()) .andDo (document ("index", links (linkWithRel ("crud" ) .description ("The CRUD resource")), responseFields (subsectionWithPath ("_ links") .description ("Links naar andere bronnen")) responseHeaders (headerWithName ("Content-Type") .description ("The Content-Type of de payload ")))); }

Hier gebruiken we de linkWithRel () methode om een ​​link naar te documenteren / crud.

Om een Inhoudstype header naar het antwoord dat we het documenteren met behulp van de headerWithName () methode en toe te voegen aan de responseHeaders () methode.

We documenteren ook de responspayload met behulp van de responseFields () methode. Dit kan worden gebruikt om een ​​meer complexe onderafdeling van het antwoord of een enkel veld te documenteren met behulp van de methoden subsectionWithPath () of fieldWithPath ().

Vergelijkbaar met de respons-payload, we kunnen de payload van het verzoek ook documenteren met requestPayload ():

@Test public void crudCreateExample () gooit uitzondering {Map crud = new HashMap (); crud.put ("titel", "Voorbeeldmodel"); crud.put ("body", "//www.baeldung.com/"); this.mockMvc.perform (post ("/ crud"). contentType (MediaTypes.HAL_JSON) .content (this.objectMapper.writeValueAsString (crud))) .andExpect (status (). isCreated ()) .andDo (document (" create-crud-example ", requestFields (fieldWithPath (" id "). description (" De id van de invoer "), fieldWithPath (" titel "). description (" De titel van de invoer "), fieldWithPath (" body " ) .description ("De inhoud van de invoer"),)))); }

In dit voorbeeld hebben we ons POST-verzoek gedocumenteerd dat een CrudInput model met titel- en hoofdtekstvelden en verzendt de status GECREËERD. Elk veld wordt gedocumenteerd met de fieldWithPath () methode.

Om verzoek en padparameter te documenteren, kunnen we de requestParameters () en pathParameters () methoden. Beide methoden gebruiken een parameterWithName () methode om elke parameter te beschrijven:

@Test public void crudDeleteExample () gooit Uitzondering {this.mockMvc.perform (delete ("/ crud / {id}", 10)). AndExpect (status (). IsOk ()) .andDo (document ("crud-delete -example ", pathParameters (parameterWithName (" id "). description (" De id van de te verwijderen invoer ")))); }

Hier hebben we ons verwijder-eindpunt gedocumenteerd dat een ID kaart padparameter.

Het Spring REST Docs-project bevat nog krachtigere documentatiefuncties, zoals veldbeperkingen en verzoekonderdelen die in de documentatie te vinden zijn.

7. Uitvoer

Zodra de build met succes is voltooid, wordt de uitvoer van de REST-documentfragmenten gegenereerd en opgeslagen in het target / generated-snippets map:

De gegenereerde uitvoer bevat de informatie over de service, hoe de REST-service moet worden aangeroepen, zoals ‘curl'-oproepen, het HTTP-verzoek en antwoord van de REST-service en links / eindpunten naar de service:

CURL-opdracht

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

HTTP - REST-reactie

[source, http, options = "nowrap"] ---- HTTP / 1.1 200 OK Inhoudstype: application / hal + json; charset = UTF-8 Inhoudslengte: 93 {"_links": {"crud": {"href": "// localhost: 8080 / crud"}}} ----

8. Fragmenten gebruiken om documentatie te maken

Om de fragmenten in een groter document te gebruiken, kunt u ernaar verwijzen met Asciidoc omvat. In ons geval hebben we een document gemaakt in src / docs gebeld api-guide.adoc:

Als we in dat document willen verwijzen naar het linkfragment, kunnen we dit opnemen met behulp van een tijdelijke aanduiding {snippets} dat wordt vervangen door Maven wanneer het het document verwerkt:

==== Links zijn: {snippets} /index-example/links.adoc []

9. Asciidocs Maven-plug-ins

Om de API-gids van Asciidoc naar een leesbaar formaat te converteren, kunnen we een Maven-plug-in toevoegen aan de build-levenscyclus. Er zijn verschillende stappen om dit mogelijk te maken:

  1. Pas de Asciidoctor-plug-in toe op het pom.xml
  2. Voeg een afhankelijkheid toe van spring-restdocs-mockmvc in de testCompile configuratie zoals vermeld in de afhankelijkheden sectie
  3. Configureer een eigenschap om de uitvoerlocatie voor gegenereerde fragmenten te definiëren
  4. Configureer het test taak om de map met fragmenten als uitvoer toe te voegen
  5. Configureer het asciidoctor taak
  6. Definieer een kenmerk met de naam fragmenten die kunnen worden gebruikt bij het opnemen van de gegenereerde fragmenten in uw documentatie
  7. Maak de taak afhankelijk van de test taak zodat de tests worden uitgevoerd voordat de documentatie wordt gemaakt
  8. Configureer het fragmenten directory als invoer. Alle gegenereerde fragmenten worden in deze map gemaakt

Voeg de fragmentmap toe als een eigenschap in pom.xml dus de Asciidoctor-plug-in kan dit pad gebruiken om de fragmenten onder deze map te genereren:

 $ {project.build.directory} / generated-snippets 

De configuratie van de Maven-plug-in in het pom.xml het genereren van de Asciidoc-fragmenten van de build is als volgt:

 org.asciidoctor asciidoctor-maven-plugin 1.5.6 genereren-docs pakket process-asciidoc html boek $ {snippetsDirectory} src / docs / asciidocs target / generated-docs 

10. API Doc Generatieproces

Wanneer de Maven-build wordt uitgevoerd en de tests worden uitgevoerd, worden alle fragmenten gegenereerd in de fragmentenmap onder de geconfigureerde target / generated-snippets directory. Zodra de fragmenten zijn gegenereerd, genereert het bouwproces HTML-uitvoer.

Het gegenereerde HTML-bestand is opgemaakt en leesbaar, dus de REST-documentatie is klaar voor gebruik. Elke keer dat de Maven-build wordt uitgevoerd, worden de documenten ook gegenereerd met de nieuwste updates.

11. Conclusie

Geen documentatie hebben is beter dan verkeerde documentatie, maar Spring REST-documenten helpen bij het genereren van nauwkeurige documentatie voor RESTful-services.

Als officieel Spring-project bereikt het zijn doelen door drie testbibliotheken te gebruiken: Spring MVC Test, WebTestClient en RUST verzekerd. Deze methode voor het genereren van documentatie kan helpen bij het ondersteunen van een testgestuurde benadering voor het ontwikkelen en documenteren van RESTful API's.

U kunt een voorbeeldproject vinden op basis van de code in dit artikel in de gekoppelde GitHub-repository.

REST onder

Ik heb zojuist het nieuwe aangekondigd Leer de lente natuurlijk, gericht op de basisprincipes van Spring 5 en Spring Boot 2:

>> BEKIJK DE CURSUS