Pengenalan kepada Dokumen Spring REST

REST Teratas

Saya baru sahaja mengumumkan kursus Learn Spring yang baru , yang berfokus pada asas-asas Spring 5 dan Spring Boot 2:

>> SEMAK KURSUS

1. Gambaran keseluruhan

Spring REST Docs menghasilkan dokumentasi untuk perkhidmatan RESTful yang tepat dan boleh dibaca. Ia menggabungkan dokumentasi tulisan tangan dengan coretan dokumen yang dihasilkan secara automatik yang dihasilkan dengan ujian Spring.

2. Kelebihan

Salah satu falsafah utama di sebalik projek ini adalah penggunaan ujian untuk menghasilkan dokumentasi. Ini memastikan bahawa dokumentasi yang dihasilkan selalu tepat dengan perilaku sebenar API. Selain itu, outputnya siap diproses oleh Asciidoctor, rantai alat penerbitan yang berpusat di sekitar sintaks AsciiDoc. Ini adalah alat yang sama yang digunakan untuk menghasilkan dokumentasi Spring Framework.

Pendekatan ini mengurangkan batasan yang dikenakan oleh kerangka lain. Spring REST Docs menghasilkan dokumentasi yang tepat, ringkas, dan tersusun dengan baik. Dokumentasi ini kemudian membolehkan pengguna perkhidmatan web mendapatkan maklumat yang mereka perlukan dengan sedikit keributan.

Alat ini mempunyai beberapa kelebihan lain, seperti:

  • coretan permintaan curl dan http dihasilkan
  • mudah mengemas dokumentasi dalam fail projek
  • senang menambahkan maklumat tambahan pada coretan
  • menyokong kedua-dua JSON dan XML

Ujian yang menghasilkan coretan boleh ditulis menggunakan sokongan Spring MVC Test, Spring Webflux's WebTestClient atau REST-Assured.

Dalam contoh kami, kami akan menggunakan ujian Spring MVC, tetapi menggunakan kerangka lain sangat serupa.

3. Kebergantungan

Cara ideal untuk memulakan penggunaan Spring REST Docs dalam projek adalah dengan menggunakan sistem pengurusan pergantungan. Di sini, kami menggunakan Maven sebagai alat binaan, jadi kebergantungan di bawah dapat disalin dan ditampal ke POM anda:

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

Anda juga boleh memeriksa Maven Central untuk versi baru kebergantungan di sini.

Dalam contoh kami, kami memerlukan pergantungan spring-restdocs-mockmvc kerana kami menggunakan sokongan ujian Spring MVC untuk membuat ujian kami.

Sekiranya kita ingin menulis ujian menggunakan WebTestClient atau REST Assured, kita memerlukan pergantungan spring-restdocs-webtestclient dan spring-restdocs-restassured.

4. Konfigurasi

Seperti yang telah disebutkan, kami akan menggunakan kerangka Uji MVC Musim Semi untuk membuat permintaan ke perkhidmatan REST yang akan didokumentasikan. Menjalankan ujian menghasilkan coretan dokumentasi untuk permintaan dan tindak balas yang dihasilkan.

Kita boleh menggunakan perpustakaan dengan ujian JUnit 4 dan JUnit 5. Mari lihat konfigurasi yang diperlukan untuk masing-masing.

4.1. Konfigurasi JUnit 4

Langkah pertama dalam menghasilkan coretan dokumentasi untuk ujian JUnit 4 adalah dengan menyatakan medan JUnitRestDocumentation awam yang dijelaskan sebagai JUnit @Rule .

The JUnitRestDocumentation peraturan dikonfigurasi dengan direktori output, ke mana coretan yang dihasilkan perlu diselamatkan. Contohnya, direktori ini boleh menjadi direktori build Maven:

@Rule public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("target/generated-snippets");

Seterusnya, kami menyediakan konteks MockMvc sehingga akan dikonfigurasi untuk menghasilkan dokumentasi:

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

The MockMvc objek dikonfigurasikan menggunakan MockMvc RestDocumentationConfigurer . Contoh kelas ini boleh didapati dari kaedah static documentationConfiguration () pada org.springframework.restdocs.mockmvc.MockMvcRestDocumentation .

4.2. Konfigurasi JUnit 5

Untuk bekerja dengan ujian JUnit 5, kita harus melanjutkan ujian dengan kelas RestDocumentationExtension :

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

Kelas ini dikonfigurasi secara automatik dengan direktori output / target / dihasilkan-snippets ketika menggunakan Maven, atau / build / menghasilkan-potongan untuk Gradle.

Seterusnya, kita harus menyediakan contoh MockMvc dalam kaedah @BeforeEach :

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

Sekiranya kita tidak menggunakan JUnit untuk ujian, maka kita harus menggunakan kelas ManualRestDocumentation .

5. Perkhidmatan TERBAIK

Mari buat perkhidmatan CRUD RESTful yang dapat kami dokumentasikan:

@RestController @RequestMapping("/crud") public class CRUDController { @GetMapping public List read(@RequestBody CrudInput crudInput) { List returnList = new ArrayList(); returnList.add(crudInput); return returnList; } @ResponseStatus(HttpStatus.CREATED) @PostMapping public HttpHeaders save(@RequestBody CrudInput crudInput) { HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setLocation( linkTo(CRUDController.class).slash(crudInput.getTitle()).toUri()); return httpHeaders; } @DeleteMapping("/{id}") public void delete(@PathVariable("id") long id) { // delete } }

Kemudian, mari kita tambahkan IndexController yang mengembalikan halaman dengan pautan ke titik akhir pangkalan CRUDController :

@RestController @RequestMapping("/") public class IndexController { static class CustomRepresentationModel extends RepresentationModel { public CustomRepresentationModel(Link initialLink) { super(initialLink); } } @GetMapping public CustomRepresentationModel index() { return new CustomRepresentationModel(linkTo(CRUDController.class).withRel("crud")); } }

6. Ujian JUnit

Kembali dalam ujian, kita dapat menggunakan instance MockMvc untuk memanggil perkhidmatan kami dan mendokumentasikan permintaan dan respons.

First, to make sure every MockMvc call is automatically documented without any further configuration we can use the alwaysDo() method:

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

This set up ensures that every for every MockMvc call, the default snippets are created in a folder with the test method's name. Also, applying the prettyPrint() pre-processor displays the snippets in a more easily-readable manner.

Let's continue with customizing some of our calls.

To document our index page which contains a link, we can use the static links() method:

@Test public void indexExample() throws Exception { this.mockMvc.perform(get("/")).andExpect(status().isOk()) .andDo(document("index", links(linkWithRel("crud").description("The CRUD resource")), responseFields(subsectionWithPath("_links") .description("Links to other resources")) responseHeaders(headerWithName("Content-Type") .description("The Content-Type of the payload")))); }

Here, we're using the linkWithRel() method to document a link to /crud.

To add a Content-Type header to the response we're documenting it using the headerWithName() method and adding it to the responseHeaders() method.

We're also documenting the response payload using the responseFields() method. This can be used to document a more complex subsection of the response or a single field using the subsectionWithPath() or fieldWithPath() methods.

Similar to the response payload, we can also document the request payload using requestPayload():

@Test public void crudCreateExample() throws Exception { Map crud = new HashMap(); crud.put("title", "Sample Model"); 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("The id of the input"), fieldWithPath("title").description("The title of the input"), fieldWithPath("body").description("The body of the input"), )))); }

In this example, we've documented our POST request that receives a CrudInput model with title and body fields and sends a CREATED status. Each field is documented using the fieldWithPath() method.

To document request and path parameter, we can use the requestParameters() and pathParameters() methods. Both methods use a parameterWithName() method to describe each parameter:

@Test public void crudDeleteExample() throws Exception { this.mockMvc.perform(delete("/crud/{id}", 10)).andExpect(status().isOk()) .andDo(document("crud-delete-example", pathParameters( parameterWithName("id").description("The id of the input to delete") ))); }

Here, we've documented our delete endpoint which receives an id path parameter.

The Spring REST Docs project contains even more powerful documentation functionalities, such as field constraints and request parts that can be found in the documentation.

7. Output

Once the build runs successfully, the output of the REST docs snippets will be generated and will be saved to the target/generated-snippets folder:

The generated output will have the information about the service, how to call the REST service like ‘curl' calls, the HTTP request and response from the REST service, and links/endpoints to the service:

CURL Command

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

HTTP – REST Response

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

8. Using Snippets to Create Documentation

To use the snippets in a larger document, you can reference them using Asciidoc includes. In our case, we have created a document in src/docs called api-guide.adoc:

In that document, if we wished to reference the links snippet, we can include it, using a placeholder {snippets} that will be replaced by Maven when it processes the document:

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

9. Asciidocs Maven Plugins

To convert the API guide from Asciidoc to a readable format, we can add a Maven plugin to the build lifecycle. There are several steps to enable this:

  1. Apply the Asciidoctor plugin to the pom.xml
  2. Add a dependency on spring-restdocs-mockmvc in the testCompile configuration as mentioned in the dependencies section
  3. Configure a property to define the output location for generated snippets
  4. Configure the test task to add the snippets directory as an output
  5. Configure the asciidoctor task
  6. Define an attribute named snippets that can be used when including the generated snippets in your documentation
  7. Make the task depend on the test task so that the tests are run before the documentation is created
  8. Configure the snippets directory as input. All the generated snippets will be created under this directory

Add the snippet directory as a property in pom.xml so the Asciidoctor plugin can use this path to generate the snippets under this folder:

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

The Maven plugin configuration in the pom.xml to generate the Asciidoc snippets from the build is as below:

 org.asciidoctor asciidoctor-maven-plugin 1.5.6   generate-docs package  process-asciidoc   html book  ${snippetsDirectory}  src/docs/asciidocs target/generated-docs    

10. API Doc Generation Process

When the Maven build runs and the tests are executed, all the snippets will be generated in the snippets folder under the configured target/generated-snippets directory. Once the snippets are generated, the build process generates HTML output.

The generated HTML file is formatted and readable, so the REST documentation is ready to use. Every time the Maven build runs, the documents also get generated with the latest updates.

11. Conclusion

Having no documentation is better than wrong documentation, but Spring REST docs will help generate accurate documentation for RESTful services.

Sebagai projek rasmi Spring, ia mencapai tujuannya dengan menggunakan tiga perpustakaan ujian: Spring MVC Test, WebTestClient dan REST Assured. Kaedah menghasilkan dokumentasi ini dapat membantu menyokong pendekatan yang didorong oleh ujian untuk membangun dan mendokumentasikan RESTful API.

Anda boleh mendapatkan contoh projek berdasarkan kod dalam artikel ini di repositori GitHub yang dipautkan.

REST bawah

Saya baru sahaja mengumumkan kursus Learn Spring yang baru , yang berfokus pada asas-asas Spring 5 dan Spring Boot 2:

>> SEMAK KURSUS