Pengantar Dokumen Spring REST

REST Top

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

>> LIHAT KURSUSnya

1. Ikhtisar

Spring REST Docs menghasilkan dokumentasi untuk layanan RESTful yang akurat dan dapat dibaca. Ini menggabungkan dokumentasi tulisan tangan dengan cuplikan dokumen yang dibuat secara otomatis yang dihasilkan dengan tes Spring.

2. Keuntungan

Salah satu filosofi utama di balik proyek ini adalah penggunaan tes untuk menghasilkan dokumentasi. Ini memastikan bahwa dokumentasi selalu dibuat secara akurat sesuai dengan perilaku API yang sebenarnya. Selain itu, keluarannya siap untuk diproses oleh Asciidoctor, sebuah rantai alat penerbitan yang berpusat di sekitar sintaks AsciiDoc. Ini adalah alat yang sama yang digunakan untuk menghasilkan dokumentasi Spring Framework.

Pendekatan ini mengurangi batasan yang diberlakukan oleh kerangka kerja lain. Spring REST Docs menghasilkan dokumentasi yang akurat, ringkas, dan terstruktur dengan baik. Dokumentasi ini kemudian memungkinkan konsumen layanan web untuk mendapatkan informasi yang mereka butuhkan dengan sedikit keributan.

Alat tersebut memiliki beberapa keunggulan lain, seperti:

  • cuplikan permintaan curl dan http dibuat
  • dokumentasi mudah untuk paket dalam file jar proyek
  • mudah untuk menambahkan informasi tambahan ke cuplikan
  • mendukung JSON dan XML

Tes yang menghasilkan cuplikan dapat ditulis menggunakan dukungan Spring MVC Test, Spring Webflux's WebTestClient atau REST-Assured.

Dalam contoh kami, kami akan menggunakan pengujian Spring MVC, tetapi menggunakan kerangka kerja lain sangat mirip.

3. Ketergantungan

Cara ideal untuk mulai menggunakan Spring REST Docs dalam sebuah proyek adalah dengan menggunakan sistem manajemen ketergantungan. Di sini, kami menggunakan Maven sebagai alat build, jadi dependensi di bawah ini dapat disalin dan ditempelkan ke POM Anda:

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

Anda juga dapat memeriksa Maven Central untuk versi baru ketergantungan di sini.

Dalam contoh kami, kami memerlukan dependensi spring-restdocs-mockmvc karena kami menggunakan dukungan pengujian Spring MVC untuk membuat pengujian kami.

Jika kita ingin menulis pengujian menggunakan WebTestClient atau REST Assured, kita memerlukan dependensi spring-restdocs-webtestclient dan spring-restdocs-restassured.

4. Konfigurasi

Seperti yang disebutkan, kami akan menggunakan kerangka kerja Spring MVC Test untuk membuat permintaan ke layanan REST yang akan didokumentasikan. Menjalankan pengujian menghasilkan cuplikan dokumentasi untuk permintaan dan respons yang dihasilkan.

Kita bisa menggunakan perpustakaan dengan tes JUnit 4 dan JUnit 5. Mari kita lihat konfigurasi yang diperlukan untuk masing-masing.

4.1. Konfigurasi JUnit 4

Langkah pertama dalam membuat cuplikan dokumentasi untuk pengujian JUnit 4 adalah mendeklarasikan kolom JUnitRestDocumentation publik yang dianotasi sebagai JUnit @Rule .

The JUnitRestDocumentation aturan dikonfigurasi dengan direktori output ke mana potongan yang dihasilkan harus disimpan. Misalnya, direktori ini dapat menjadi direktori build out Maven:

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

Selanjutnya, kami menyiapkan 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 dikonfigurasi menggunakan MockMvc RestDocumentationConfigurer . Instance dari kelas ini bisa diperoleh dari metode dokumentasiConfiguration () statis di org.springframework.restdocs.mockmvc.MockMvcRestDocumentation .

4.2. Konfigurasi JUnit 5

Untuk bekerja dengan pengujian JUnit 5, kita harus memperluas pengujian dengan kelas RestDocumentationExtension :

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

Kelas ini secara otomatis dikonfigurasi dengan direktori output / target / generated-snippet saat menggunakan Maven, atau / build / generate-snippet untuk Gradle.

Selanjutnya, kita harus menyiapkan instance MockMvc dalam metode @BeforeEach :

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

Jika kita tidak menggunakan JUnit untuk pengujian, maka kita harus menggunakan kelas ManualRestDocumentation .

5. Layanan RESTful

Mari buat layanan CRUD RESTful yang dapat kita 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 tambahkan juga IndexController yang mengembalikan halaman dengan tautan ke titik akhir basis 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. Tes JUnit

Kembali dalam pengujian, kami dapat menggunakan instance MockMvc untuk memanggil layanan 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 proyek Spring resmi, ia mencapai tujuannya dengan menggunakan tiga pustaka pengujian: Spring MVC Test, WebTestClient , dan REST Assured. Metode pembuatan dokumentasi ini dapat membantu mendukung pendekatan berbasis pengujian untuk mengembangkan dan mendokumentasikan RESTful API.

Anda dapat menemukan proyek contoh berdasarkan kode dalam artikel ini di repositori GitHub yang ditautkan.

REST bawah

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

>> LIHAT KURSUSnya