Jarné dokumenty REST vs OpenAPI

ODPOČINOK Najlepšie

Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:

>> SKONTROLUJTE KURZ

1. Prehľad

Dokumenty Spring REST Docs a OpenAPI 3.0 sú dva spôsoby, ako vytvoriť dokumentáciu API pre REST API.

V tomto návode preskúmame ich relatívne výhody a nevýhody.

2. Stručné zhrnutie pôvodu

Spring REST Docs je rámec vyvinutý komunitou Spring s cieľom vytvoriť presnú dokumentáciu pre RESTful API. Vyžaduje si prístup založený na testoch, pričom dokumentácia je napísaná buď ako jarné testy MVC, jarné Webflux WebTestClient, alebo REST-Assured.

Výsledok vykonania testov je vytvorený ako súbory AsciiDoc, ktoré je možné zostaviť pomocou nástroja Asciidoctor na vygenerovanie stránky HTML s popisom našich rozhraní API. Pretože sa riadi metódou TDD, Spring REST Docs automaticky prináša všetky svoje výhody ako napríklad kód náchylnejší na chyby, menej prepracovania a rýchlejšie cykly spätnej väzby.

OpenAPI je na druhej strane špecifikácia pochádzajúca zo Swagger 2.0. Jeho posledná verzia od písania tohto článku je 3.0 a má veľa známych implementácií.

Ako každá iná špecifikácia, OpenAPI stanovuje určité základné pravidlá, podľa ktorých sa jeho implementácie majú riadiť. Jednoducho povedané, všetko Implementácie OpenAPI majú produkovať dokumentáciu ako objekt JSON, a to buď vo formáte JSON, alebo YAML.

Existuje tiež veľa nástrojov, ktoré používajú tento JSON / YAML a vypľúvajú používateľské rozhranie na vizualizáciu a navigáciu rozhrania API. To sa hodí napríklad pri preberacích testoch. V našich ukážkach kódu, ktoré tu použijeme springdoc - knižnica pre OpenAPI 3 s Spring Boot.

Predtým, ako sa podrobne pozrieme na tieto dva, rýchlo nastavíme API, ktoré sa má zdokumentovať.

3. REST API

Zostavme základné CRUD API pomocou Spring Boot.

3.1. Úložisko

Repozitár, ktorý budeme používať, je holá kosť PagingAndSortingRepository rozhranie s modelom Foo:

@Repository verejné rozhranie FooRepository rozširuje PagingAndSortingRepository {} @Entity verejná trieda Foo {@Id @GeneratedValue (strategy = GenerationType.IDENTITY) súkromné ​​dlhé ID; @Column (nullable = false) názov súkromného reťazca; @Column () súkromné ​​telo reťazca; // konštruktor, getri a nastavovatelia}

Repozitár tiež načítame pomocou a schema.sql a a data.sql.

3.2. Kontrolór

Ďalej sa pozrime na ovládač, ktorý z dôvodu stručnosti preskočí podrobnosti jeho implementácie:

@RestController @RequestMapping ("/ foo") verejná trieda FooController {@Autowired úložisko FooRepository; @GetMapping public ResponseEntity getAllFoos () {// implementation} @GetMapping (value = "{id}") public ResponseEntity getFooById (@PathVariable ("id") Long id) {// implementation} @PostMapping public ResponseEntity addFoo (@RequestBody @Valid Foo foo ) {// implementation} @DeleteMapping ("/ {id}") public ResponseEntity deleteFoo (@PathVariable ("id") long id) {// implementation} @PutMapping ("/ {id}") public ResponseEntity updateFoo (@ PathVariable ("id") dlhé ID, @RequestBody Foo foo) {// implementácia}}

3.3. Aplikácia

A nakoniec Boot App:

@SpringBootApplication () verejná trieda Aplikácia {verejné statické void main (String [] args) {SpringApplication.run (Application.class, args); }}

4. OpenAPI / Springdoc

Teraz sa pozrime ako springdoc môže pridať dokumentáciu k nášmu Foo REST API.

Pripomeňme si to vygeneruje objekt JSON a vizualizáciu používateľského rozhrania API na základe tohto objektu.

4.1. Základné používateľské rozhranie

Na začiatok pridáme niekoľko závislostí Maven - springdoc-openapi-data-rest na generovanie JSON a springdoc-openapi-ui na vykreslenie UI.

Tento nástroj skontroluje kód nášho API a prečíta anotácie metód kontrolóra. Na tomto základe vygeneruje API JSON, ktorý bude zverejnený v // localhost: 8080 / api-docs /. Poskytuje tiež základné používateľské rozhranie na adrese //localhost:8080/swagger-ui-custom.html:

Ako vidíme, bez pridania kódu sme získali nádhernú vizualizáciu nášho API, až po Foo schéma. Pomocou Vyskúšaj to tlačidlo, môžeme dokonca vykonať operácie a zobraziť výsledky.

Teraz, čo keby sme chceli pridať k API nejakú skutočnú dokumentáciu? Z hľadiska toho, o čom je API, čo znamenajú všetky jeho operácie, aké by mali byť vstupy a aké reakcie možno očakávať?

Na to sa pozrieme v nasledujúcej časti.

4.2. Podrobné používateľské rozhranie

Najprv sa pozrime, ako pridať všeobecný popis k API.

Za to pridáme OpenAPI fazuľa do našej bootovacej aplikácie:

@Bean public OpenAPI customOpenAPI (@Value ("$ {springdoc.version}") String appVersion) {return new OpenAPI (). Info (new Info () .title ("Foobar API") .version (appVersion) .description ( „Toto je ukážkový server Foobar vytvorený pomocou Springdocs -" + "knižnice pre OpenAPI 3 s jarným bootovaním.") .TermsOfService ("// swagger.io/terms/") .license (nová licencia (). Name (" Apache 2.0 ") .url (" // springdoc.org "))); } 

Ďalej, aby sme pridali nejaké informácie do našich operácií API, ozdobíme naše mapovania niekoľkými anotáciami špecifickými pre OpenAPI.

Pozrime sa, ako to môžeme opísať getFooById. Urobíme to vo vnútri iného radiča, FooBarController, ktorý je podobný nášmu FooController:

@RestController @RequestMapping ("/ foobar") @Tag (name = "foobar", description = "rozhranie foobar API s anotáciami dokumentácie") verejná trieda FooBarController {@Autowired úložisko FooRepository; @Operation (summary = "Get a foo by foo id") @ApiResponses (value = {@ApiResponse (responseCode = "200", description = "found the foo", content = {@Content (mediaType = "application / json") , schema = @Schema (implementation = Foo.class))}), @ApiResponse (responseCode = "400", description = "Zadané neplatné ID", content = @Content), @ApiResponse (responseCode = "404", description = „Foo not found“, content = @Content)}) @GetMapping (value = "{id}") public ResponseEntity getFooById (@Parameter (description = "id of foo to be searched") @PathVariable ("id") String id) {// implementácia vynechaná pre stručnosť} // ďalšie mapovania, podobne anotované pomocou @Operation a @ApiResponses} 

Teraz sa pozrime na vplyv na užívateľské rozhranie:

Takže s týmito minimálnymi konfiguráciami môže používateľ nášho API teraz vidieť, o čo ide, ako ho používať a aké výsledky možno očakávať. Všetko, čo sme museli urobiť, bolo zostaviť kód a spustiť aplikáciu Boot.

5. Jarné REST dokumenty

Dokumenty REST sú v dokumentácii API úplne odlišné. Ako už bolo popísané vyššie, proces je riadený testom a výstup je vo forme statickej stránky HTML.

V našom príklade tu na vytvorenie úryvkov dokumentácie použijeme jarné testy MVC.

Na začiatok budeme musieť pridať spring-restdocs-mockmvc závislosť a asciidoc Maven plugin do nášho pom.

5.1. Test JUnit5

Poďme sa teraz pozrieť na test JUnit5, ktorý obsahuje našu dokumentáciu:

@ExtendWith ({RestDocumentationExtension.class, SpringExtension.class}) @SpringBootTest (triedy = Application.class) verejná trieda SpringRestDocsIntegrationTest {private MockMvc mockMvc; @Autowired private ObjectMapper objectMapper; @BeforeEach public void setup (WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {this.mockMvc = MockMvcBuilders.webAppContextSetup (webApplicationContext) .apply (documentationConfiguration) (restDocumentation) } @Test public void whenGetFooById_thenSuccessful () throws Exception {ConstraintDescriptions desc = new ConstraintDescriptions (Foo.class); this.mockMvc.perform (get ("/ foo / {id}", 1)) .andExpect (status (). isOk ()) .andDo (document ("getAFoo", preprocessRequest (prettyPrint ()), preprocessResponse (prettyPrint) ()), pathParameters (parameterWithName ("id"). description ("id foo to be searched")), responseFields (fieldWithPath ("id")) .description ("ID foo" + collectionToDelimitedString (desc.descriptionsForProperty ("id"), ".")), fieldWithPath ("titul"). description ("Názov foo"), fieldWithPath ("body"). description ("Telo foo")))) ; } // viac testovacích metód na pokrytie iných mapovaní

}

Po vykonaní tohto testu dostaneme niekoľko súborov v našom ciele / generované úryvky adresár s informáciami o danej operácii API. Obzvlášť, whenGetFooById_thenSuccessful dá nám osem adocs v a getAFoo priečinok v adresári.

Tu je ukážka http-response.adoc, samozrejme obsahujúci orgán odpovede:

[source, http, options = "nowrap"] ---- HTTP / 1.1 200 OK Content-Type: application / json Content-Length: 60 {"id": 1, "title": "Foo 1", "body ":" Foo body 1 "} ----

5.2. fooapi.adoc

Teraz potrebujeme hlavný súbor, ktorý spojí všetky tieto úryvky dohromady a vytvorí dobre štruktúrovaný kód HTML.

Nazvime to fooapi.adoc a uvidíte jeho malú časť:

=== Prístup k foo GET Požiadavka `GET` sa používa na prístup k foo readu. ==== Zahrnúť štruktúru žiadosti :: {{snippets} /getAFoo/http-request.adoc [] ==== Zahrnúť parametre cesty :: {snippets} /getAFoo/path-parameters.adoc [] ==== Príklad odpovede zahrnúť :: {snippets} /getAFoo/http-response.adoc [] ==== žiadosť CURL zahrnúť :: {{snippets} /getAFoo/curl-request.adoc []

Po vykonaní asciidoctor-maven-plugin, dostaneme konečný súbor HTML fooapi.html v cieľ / generované-dokumenty priečinok.

Takto to bude vyzerať po otvorení v prehliadači:

6. Kľúčové jedlá

Teraz, keď sme sa pozreli na obe implementácie, zhrňme si výhody a nevýhody.

S springdoc, anotácie, ktoré sme museli použiť, zahltili kód nášho odpočívadla a znížili jeho čitateľnosť. Dokumentácia bola tiež pevne spojená s kódom a dostala sa do výroby.

Netreba dodávať, že údržba dokumentácie je ďalšou výzvou - ak by sa niečo v API zmenilo, nezabudol by si programátor vždy aktualizovať zodpovedajúcu anotáciu OpenAPI?

Na druhej strane, Dokumenty REST nevyzerajú tak chytľavo ako iné používateľské rozhranie, ani ich nemožno použiť na akceptačné testovanie. Má to však svoje výhody.

Pozoruhodné je najmä úspešné dokončenie jarný test MVC nám poskytuje nielen úryvky, ale overuje aj naše API, ako by to robil akýkoľvek iný test jednotky. To nás núti vykonávať zmeny dokumentácie zodpovedajúce prípadným úpravám API. Kód dokumentácie je tiež úplne oddelený od implementácie.

Ale zase na druhú stranu, museli sme napísať viac kódu na vygenerovanie dokumentácie. Po prvé, samotný test, ktorý je pravdepodobne rovnako podrobný ako anotácie OpenAPI, a po druhé, hlavný adoc.

Potrebuje tiež viac krokov na vygenerovanie konečného kódu HTML - najskôr spustenie testu a potom doplnku. Springdoc vyžaduje iba spustenie aplikácie Boot.

7. Záver

V tomto tutoriáli sme sa pozreli na rozdiely medzi OpenAPI springdoc a jarné dokumenty REST. Tiež sme videli, ako implementovať tieto dva nástroje na generovanie dokumentácie pre základné CRUD API.

Stručne povedané, obe majú svoje klady a zápory a rozhodnutie o použití jedného nad druhým podlieha našim špecifickým požiadavkám.

Ako vždy, zdrojový kód je k dispozícii na GitHub.

REST spodok

Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:

>> SKONTROLUJTE KURZ

$config[zx-auto] not found$config[zx-overlay] not found