What is a Swagger
Swagger is a series of RESTful API tools, through Swagger can obtain an interactive document of the project, client SDK automatic generation and other functions.
Swagger’s goal is to define a standard, language-neutral interface for REST APIs that enables people and computers to discover and understand the capabilities of various services without access to source code or documentation or network traffic detection. When the service is defined by Swagger, the consumer can interact with the remote service with a little implementation logic. Like a low-level programming interface, Swagger takes a lot of the guesswork out of calling services.
Swagger is the most popular API in the world.
Swagger is a simple but powerful API presentation tool. It has the largest API tool ecosystem on the planet, with thousands of developers, using almost every modern programming language, all supporting and using Swagger. Using the Swagger generation API, we can get interactive documentation, an SDK for automatically generating code, and API discovery features.
The idea of integrating Swagger with Spring Boot is to use annotations to mark up information that needs to be displayed in API documents, and Swagger will generate corresponding API documents based on the annotations marked in the project. Swagger is known as the most popular API tool in the world, it provides a complete solution for API management, API document management needs to consider the basic factors, here will explain the most common customization content.
Quick learning
Spring Boot integration with Swagger 2.X is easy to implement. It requires the introduction of dependencies and basic configuration.
Adding a dependency package
< the dependency > < groupId > IO. Springfox < / groupId > < artifactId > springfox - swagger2 < / artifactId > < version > 2.8.0 < / version > </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> The < version > 2.8.0 < / version > < / dependency >Copy the code
Create the SwaggerConfig configuration class
@Configuration
@EnableSwagger2
public class SwaggerConfig {
}
Copy the code
Add two annotations to SwaggerConfig’s class:
- @configuration. This class is loaded at startup
- @enablesWagger2, indicates that this project enables Swagger API documentation
Add two methods to SwaggerConfig:
@ Bean public Docket API () {return new Docket (DocumentationType. SWAGGER_2). ApiInfo (apiInfo ()). The select () / / to modify for their own path .apis(RequestHandlerSelectors.basePackage("com.neo.xxx")) .paths(PathSelectors.any()) .build(); }Copy the code
This method uses @bean, initialized at startup, returns instance Docket (Swagger API abstract), It is important to note here. The apis (RequestHandlerSelectors basePackage (com. Neo. “XXX”)) need to scan the package specified path, only the path of the Controller will automatically generate Swagger API documentation.
Private ApiInfo ApiInfo () {return new ApiInfoBuilder().title(" client management ").description(" client management API 1.0 operation documentation ") // Terms of Service url TermsOfServiceUrl (" http://www.ityouknow.com/ "). The version (" 1.0 "). Contact (new contact (" pure smile," "http://www.ityouknow.com/", "[email protected]")) .build(); }Copy the code
This configuration is relatively important. The basic information displayed on the main configuration page includes title, description, version, terms of service, and contact information. Check the source code of the ApiInfo class to find that license configuration is supported.
public class ApiInfo { public static final Contact DEFAULT_CONTACT = new Contact("", "", ""); public static final ApiInfo DEFAULT; private final String version; private final String title; private final String description; private final String termsOfServiceUrl; private final String license; private final String licenseUrl; private final Contact contact; private final List<VendorExtension> vendorExtensions; / /... }Copy the code
All of the above information can be configured in this method, or the default values can be used. Start the project after configuration is complete, enter http://localhost:8080/swagger-ui.html in the browser, you can see the above configuration information, the effect is as follows:
No Operations defined in spec! “, meaning that the relevant API content is not found, because the corresponding Controller information has not been added, the following code will introduce the use of each annotation one by one.
Swagger
Swagger indicates that the interface will generate documents through annotations, including interface name, request method, parameters, returned information, etc. Commonly used annotations are as follows:
scope | API | Use location |
---|---|---|
Protocol Set Description | @Api | For the Controller class |
Protocol description | @ApiOperation | Let’s use the Controller method |
A non-object parameter set | @ApiImplicitParams | In the @apiImplicitParams method |
The response set | @ApiResponses | Let’s use the Controller method |
Response information parameter | @ApiResponse | Used in @ApiResponses |
Describes the meaning of the returned object | @ApiModel | Used on return object classes |
Object properties | @ApiModelProperty | Used on fields of the inbound and outbound parameter objects |
Build on the example project covered in Lessons 2-8 and add examples of RESTful API documentation.
@ the use of Api
The Api applies to the Controller Class as a Swagger resource. This annotation marks a Controller (Class) as a Swagger resource (Api). By default, Swagger-core only scans and resolves classes with @API annotations, and automatically ignores annotations from other categories of resources (JAX-RS endpoints, Servlets, and so on).
Example:
@api (value = "message ", description =" message operation Api ", position = 100, protocols = "http") @RestController @RequestMapping("/") public class MessageController { }Copy the code
Used in conjunction with the Controller annotation, the properties are configured as shown in the table:
The attribute name | note |
---|---|
value | Path value of the URL |
tags | If you set this value, the value of value is overwritten |
description | Description of API resources |
produces | For example, “application/json, application/xml” |
consumes | For example, “application/json, application/xml” |
protocols | Possible values: http, https, ws, wss |
authorizations | This parameter is configured for advanced feature authentication |
hidden | Setting it to true will be hidden in the document |
After the restart the project, input http://localhost:8080/swagger-ui.html#/message-controller in the browser, you can see the following effects:
The methods in the MessageController are automatically mapped and the request method for each method is indicated.
The use of the @ ApiOperation
ApiOperation is defined on a method and describes the method name, method interpretation, return information, tags, and other information.
Example:
@APIOperation (value =" message list ", Notes =" Complete message content list ", Produces ="application/json, application/ XML ", consumes="application/json, application/xml", response = List.class) @GetMapping(value = "messages") public List<Message> list() { }Copy the code
The attribute name | note |
---|---|
value | Path value of the URL |
tags | If you set this value, the value of value will be overwritten |
produces | For example, “application/json, application/xml” |
consumes | For example, “application/json, application/xml” |
protocols | Possible values: http, https, ws, wss |
authorizations | This parameter is configured for advanced feature authentication |
hidden | Setting it to true will be hidden in the document |
response | Object returned |
responseContainer | These objects are valid “List”, “Set” or “Map”, and others are invalid |
httpMethod | “GET”, “HEAD”, “POST”, “PUT”, “DELETE”, “OPTIONS” and “PATCH” |
code | The default HTTP status code is 200 |
extensions | Extended attributes |
After the restart the project, input http://localhost:8080/swagger-ui.html#/message-controller/listUsingGET in the browser, you can see the following effects:
Use of @apiIMPLicitParams and @apiIMPLicitParam
@apiIMPLICITParams is used to describe the information returned by the method, in conjunction with the @apiIMPLicitParam annotation; @apiIMPLICITParam Describes information about a parameter, including the parameter name, type, and limit.
Example:
@apiImplICITParams ({@apiIMPLICITParam (name = "id", value = "message ID", Required = true, dataType = "Long", paramType = "query"), @APIIMPLICITParam (name = "text", value = "text", Required = true, dataType = "String", paramType = "query"), @APIIMPLICITParam (name = "summary", value = "summary", required = false, dataType = "String", paramType = "query"), }) @PostMapping(value = "message") public Message create(Message message) { }Copy the code
The attribute name | note |
---|---|
Name Name of the receiving parameter | |
Value Indicates the description of the received parameters | |
Whether the required parameter must be true or false | |
The dataType of the dataType parameter is indicated only as a flag and is not actually validated |
ParamType Specifies the query parameter type. The value is as follows: Path submits data as an address query automatically maps directly to parameters Body submits data as a stream, Only the POST header parameter is supported. Submit a form from request Headers. Submit the form as a form
After the restart the project, input http://localhost:8080/swagger-ui.html#/message-controller/createUsingPOST in the browser, you can see the following effects:
The use of @apiresponses and @apiResponse
@APIresponses mainly encapsulates the return information of the method and @APIResponse is configured to be used. @APIResponse defines the specific information returned, including return code and return information.
Example:
@apiOperation (value = "modify message ", Notes = "Modify messages according to parameters ") @putMapping (value = "message") @apiresponses ({@apiResponse (code = 100, message =" request parameters wrong "), @apiResponse (code = 101, message = "unauthorized "), @apiResponse (code = 103, message =" forbidden "), @apiResponse (code = 104, message = "forbidden "), @apiResponse (code = 104, message =" forbidden "), Message = "request path not found "), @apiResponse (code = 200, message =" server internal error ")}) public message modify(message message) {}Copy the code
The attribute name | note |
---|
Code HTTP status code Message Description Response Default response class Void Reference Reference responseHeaders Encapsulation Return information responseContainer A character string
After the restart the project, input http://localhost:8080/swagger-ui.html#/message-controller/modifyUsingPUT in the browser, you can see the following effects:
Use of @APIModel and @APIModelProperty
In real projects, we often encapsulate an object as a return value. @APIModel is responsible for describing the information of the object, and @APIModelProperty is responsible for describing the properties of the object.
Example:
@apiModel (description = "response object ") public class BaseResult<T> {private static final int SUCCESS_CODE = 0; Private static final String SUCCESS_MESSAGE = "success "; @APIModelProperty (value = "response code", name = "code", Required = true, example =" + SUCCESS_CODE) private int code; @APIModelProperty (value = "response message ", name =" MSG ", Required = true, example = SUCCESS_MESSAGE) private String MSG; @apiModelProperty (value = "data", name = "data") private T data; }Copy the code
The following table shows the attribute configuration:
The attribute name | note |
---|---|
value | Property description |
name | If override attribute name is configured |
allowableValues | Allowed values |
access | Do not configure |
notes | Don’t use |
dataType | The data type |
required | Specifies whether this parameter is mandatory |
position | The sequential position displayed |
hidden | If so |
example | For example, |
readOnly | read-only |
reference | reference |
So we can wrap the return information in the Controller like this:
@PatchMapping(value="/message/text")
public BaseResult<Message> patch(Message message) {
Message messageResult=this.messageRepository.updateText(message);
return BaseResult.successWithData(messageResult);
}
Copy the code
After the restart the project, input http://localhost:8080/swagger-ui.html in the browser, why page Models drawer, you can see the following effects:
These are some of the most commonly used annotations in a project and can be used flexibly to automatically build clear API documentation.
Try it out
The online API created with Swagger also has a very powerful capability to test the availability of the interface directly on the page, making it very convenient to use this capability for interface validation in the event of problems with front-end and back-end interface debugging. In the above parameter explanation, we found that there is a button “Try it Out” on the right of each interface description. Click “Try it Out” to enter the form page, as follows:
Curl curl curl curl curl curl curl curl curl curl curl curl curl curl
curl -X POST "http://localhost:8080/message? id=6&summary=%E8%BF%99%E6%98%AF%E4%B8%80%E4%B8%AA%E6%B6%88%E6%81%AF&text=hello" -H "accept: */*"Copy the code
You can see the change of the parameters of the curl command by adjusting Swagger parameters in the back end.
Export the Swagger2 document using Swagger2Markup
Introduce dependencies and plug-ins
<! <dependency> <groupId> IO. Github. Swagger2markup </groupId> <artifactId> The < version > 1.3.3 < / version > < / dependency >Copy the code
<! -> < plugins > -> < plugins > < the groupId > org. Asciidoctor < / groupId > < artifactId > asciidoctor maven - plugin < / artifactId > < version > 1.5.6 < / version > <configuration> <sourceDirectory>./docs/asciidoc/generated</sourceDirectory>
<outputDirectory>./docs/asciidoc/html</outputDirectory>
<headerFooter>true</headerFooter>
<doctype>book</doctype>
<backend>html</backend>
<sourceHighlighter>coderay</sourceHighlighter> <attributes> <! Menu bar on the left --> <toc>left</ TOC > <! 3</toclevels> <! --> <sectnums>true</sectnums>
</attributes>
</configuration>
</plugin>
Copy the code
Full of pom
<? xml version="1.0" encoding="UTF-8"? > <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> < modelVersion > 4.0.0 < / modelVersion > < the parent > < groupId > org. Springframework. Boot < / groupId > The < artifactId > spring - the boot - starter - parent < / artifactId > < version > 2.2.2. RELEASE < / version > < relativePath / > <! -- lookup parent from repository --> </parent> <groupId>com.lichongbing</groupId> < artifactId > springboot -- learn -- swagger docs - study < / artifactId > < version > 0.0.1 - the SNAPSHOT < / version > <name>springboot-learn-swagger-docs-study</name> <description>Demo projectforSpring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> < the groupId > IO. Springfox < / groupId > < artifactId > springfox - swagger2 < / artifactId > < version > 2.9.2 < / version > < / dependency > < the dependency > < groupId > IO. Springfox < / groupId > < artifactId > springfox swagger - UI < / artifactId > < version > 2.9.2 < / version > </dependency> <! --> <dependency> <groupId> IO. Github. Swagger2markup </groupId> <artifactId> < version > 1.3.3 < / version > < / dependency > < the dependency > < groupId > nl. Jworks. Markdown_to_asciidoc < / groupId > < artifactId > markdown_to_asciidoc < / artifactId > < version > 1.1 sources < / version > < / dependency > < the dependency > <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <! -> < plugins > -> < plugins > < the groupId > org. Asciidoctor < / groupId > < artifactId > asciidoctor maven - plugin < / artifactId > < version > 1.5.6 < / version > <configuration> <sourceDirectory>./docs/asciidoc/generated</sourceDirectory>
<outputDirectory>./docs/asciidoc/html</outputDirectory>
<headerFooter>true</headerFooter>
<doctype>book</doctype>
<backend>html</backend>
<sourceHighlighter>coderay</sourceHighlighter> <attributes> <! Menu bar on the left --> <toc>left</ TOC > <! 3</toclevels> <! --> <sectnums>true</sectnums>
</attributes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Copy the code
Write a test class
package com.lichongbing; import io.github.swagger2markup.GroupBy; import io.github.swagger2markup.Language; import io.github.swagger2markup.Swagger2MarkupConfig; import io.github.swagger2markup.Swagger2MarkupConverter; import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder; import io.github.swagger2markup.markup.builder.MarkupLanguage; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.net.URL; import java.nio.file.Paths; /** * @author lichongbing * @email [email protected] * @date 2020/01/02 19:31 * com.lichongbing */ @runwith (springrunner.class) @SpringbooTtest Public Class ApplicationIntfTests {/** * Generates AsciiDocs format documents ** @throws Exception */ @test public void generateAsciiDocs() throws Exception {// Output the Ascii format Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.ASCIIDOC) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))
.withConfig(config)
.build()
.toFolder(Paths.get("./docs/asciidoc/generated")); } /** * Generate Markdown format documents ** @throws Exception */ @test public void generateMarkdownDocs() throws Exception {// Output format Markdown Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder () .withMarkupLanguage(MarkupLanguage.MARKDOWN) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))
.withConfig(config)
.build()
.toFolder(Paths.get("./docs/markdown/generated")); ** * Throws Exception */ @test public void generateConfluenceDocs() throws Exception {// The format of the output Confluence was using Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder () .withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))
.withConfig(config)
.build()
.toFolder(Paths.get("./docs/confluence/generated")); } /** * Generate an AsciiDocs document and aggregate it into a file ** @throws Exception */ @test public void generateAsciiDocsToFile() throws Exception { / / output Ascii to single file Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder () .withMarkupLanguage(MarkupLanguage.ASCIIDOC) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))
.withConfig(config)
.build()
.toFile(Paths.get("./docs/asciidoc/generated/all")); } / * * * generate Markdown document format, and rolled into a file * * @ throws the Exception * / @ Test public void generateMarkdownDocsToFile () throws the Exception {/ / output Markdown to single file Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder () .withMarkupLanguage(MarkupLanguage.MARKDOWN) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))
.withConfig(config)
.build()
.toFile(Paths.get("./docs/markdown/generated/all")); }}Copy the code
Start the project, get the ADDRESS of the JSON file, and then close the project, otherwise the port will be reported to be occupied when the test is allowed later
Run the five tests in Step 2. If the docs/ Markdown folder does not exist, create the folder manually. If there are no exceptions, generated generates an. Adoc file
.├ ── all. ├── All. ├── All ├─ ├─ TXT ├─ TXT ├─ TXT ├─ TXT ├─ TXT ├─ TXT ├─ TXT ├─ TXT ├─ TXT ├─ TXT └── all. School exercises ── all. School Exercises ─ allCopy the code
Run the Maven command asciidoctor:process-asciidoc to generate the HTML
mvn asciidoctor:process-asciidoc
Copy the code
That’s it. Just go to all.html
├ ─ ─ asciidoc │ ├ ─ ─ generated │ │ ├ ─ ─ all the adoc │ │ ├ ─ ─ definitions. The adoc │ │ ├ ─ ─ the overview. The adoc │ │ ├ ─ ─ paths. The adoc │ │ └ ─ ─ Security. The adoc │ └ ─ ─ HTML │ ├ ─ ─ all the HTML │ ├ ─ ─ definitions. The HTML │ ├ ─ ─ the overview. The HTML │ ├ ─ ─ paths. The HTML │ └ ─ ─ security. The HTML ├ ─ ─ confluence was │ └ ─ ─ generated │ ├ ─ ─ definitions. TXT │ ├ ─ ─ the overview. TXT │ ├ ─ ─ paths. TXT │ └ ─ ─ security. TXT └ ─ ─ markdown └── all. School exercises ── definitions. School ExercisesCopy the code
conclusion
Through the learning of this lesson, we have mastered the use of Swagger in Spring Boot project, and rich API documents can be easily constructed by using Swagger’s relevant annotations. Using Swagger can help generate standard API documentation to avoid inefficient communication in interface interaction. As a powerful API generation framework, Swagger actually has more functions, so you can have the opportunity to continue learning offline.
Click here to download the source.
Springboot2. X integrates Swagger2 and outputs offline documents in HTML, ADOc, Markdown, and text formats