preface

I believe that many back-end development projects will encounter the need to write API documents, whether it is to provide a better connection to the front end, mobile terminal, etc., or in order to facilitate the future handover, will require to write API documents.

Writing API documents by hand has a lot of pain points:

  • When the document is updated, it needs to be sent to the peer again
  • The interfaces are too right to manage handwritten documents
  • The result returned by the interface is not clear
  • The interface cannot be tested online directly, usually using a tool such as Postman

Swagger solves this problem perfectly.

Introduction of Swagger

Swagger is a canonical and complete framework for generating, describing, invoking, and visualizing RESTful Web services. The overall goal is to have clients and file systems update at the same rate as servers. File methods, parameters, and models are tightly integrated into server-side code, allowing the API to always be in sync.

Liverpoolfc.tv: swagger. IO

Swagger use

1. Dependent dependencies

<! --swagger2 --> <dependency> <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 >Copy the code

2. The Swagger configuration class

@Configuration
@EnableSwagger2
public class SwaggerConfig {
	@Bean
    public Docket buildDocket() {
        returnNew Docket (DocumentationType SWAGGER_2). ApiInfo (buildApiInf ()) / / sets the API's meta information is included in the json resourcelisting response / /. The host ("127.0.0.1:8080") // Set the IP address and port, Or domain name. The select () / / start for API choice of generator / /. Apis (RequestHandlerSelectors. Any ()). The apis (RequestHandlerSelectors. BasePackage ("cn.zwqh.springboot.controller"Paths (PathSelectors. Any ()).build(); } private ApiInfobuildApiInf() {
    	
        Contact contact=new Contact("Morning fog light cold"."https://www.zwqh.top/"."[email protected]");
        return new ApiInfoBuilder()
        .title("Swagger Demo Restful API Docs"// Document title.description ("Swagger Example Restful Api documentation"Contact (contact)// contact.version ("1.0")// Version number //. License (""// Update the license information for this API //.licenseurl ("")// Update the license Url for this API //.termsofServiceurl ("")// Update the terms of Service url.build (); }}Copy the code

3. Configure Spring MVC

@ Configuration public class WebMvcConfig extends WebMvcConfigurationSupport {/ * * * static resource allocation (the default) * / @ Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/ * *").addResourceLocations("classpath:/static/"); / / static resource path registry. AddResourceHandler ("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
		registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); super.addResourceHandlers(registry); }}Copy the code

If you do not add this static resource configuration, an error is reported and the related path cannot be found

4. Use Swagger annotations in Model

@ApiModel(value = "UserEntity", description = "User Object")
public class UserEntity implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 5237730257103305078L;
	@ApiModelProperty(value ="User id",name="id",dataType="Long",required = false,example = "1",hidden = false )
	private Long id;
	@ApiModelProperty(value ="Username",name="userName",dataType="String",required = false,example = "Guan yu" )
	private String userName;
	@ApiModelProperty(value ="User gender",name="userSex",dataType="String",required = false,example = "Male" )
	private String userSex;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getUserSex() {
		return userSex;
	}

	public void setUserSex(String userSex) { this.userSex = userSex; }}Copy the code

5. Use Swagger annotations in Controller


@RestController
@RequestMapping("/api")
@Api(tags = { "Interface Group 1"."Interface Group 2" })
public class ApiController {

	@Autowired
	private UserDao userDao;

	@GetMapping("/getAllUser")
	@ApiOperation(value = "Get all users", notes = "", httpMethod = "GET", tags = "Interface Group 3")
	public List<UserEntity> getAll() {
		return userDao.getAll();
	}

	@GetMapping("/getUserById")
	@ApiOperation(value = "Get user by ID", notes = "Id will preach", httpMethod = "GET")
	@ApiImplicitParam(name = "id", value = "User id",example = "1", required = true, dataType = "long", paramType = "query")
	public UserEntity getOne(Long id) {
		return userDao.getOne(id);
	}

	@PostMapping("/getUserByNameAndSex")
	@ApiOperation(value = "Get users by name and sex", notes = "", httpMethod = "POST")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "userName", value = "Username", example = "Guan yu", required = true, dataType = "string", paramType = "query"),
			@ApiImplicitParam(name = "userSex", value = "User gender", example = "Male", required = true, dataType = "string", paramType = "query") })
	public UserEntity getUserByNameAndSex(String userName, String userSex) {
		return userDao.getUserByNameAndSex(userName, userSex);
	}

	@PostMapping("/insertUser")
	@ApiOperation(value = "New User", notes = "Pass JSON, put body", httpMethod = "POST")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "body", value = "User object JSON", example = "{userName:' light cold ',userSex:' male '}", required = true) })
	public String insertUser(@RequestBody String body) {
		System.out.println(body);
		UserEntity user = JSON.parseObject(body, UserEntity.class);
		userDao.insertUser(user);
		return "{code:0,msg:'success'}";
	}

	@PostMapping("/updateUser")
	@ApiOperation(value = "Modify user", notes = "Pass JSON, put body", httpMethod = "POST")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "body", value = "User object JSON", example = "{id:23, userSex:' female '}", required = true) })
	public String updateUser(@RequestBody String body) {
		System.out.println(body);
		UserEntity user = JSON.parseObject(body, UserEntity.class);
		userDao.updateUser(user);
		return "{code:0,msg:'success'}";
	}

	@PostMapping("/deleteUser")
	@ApiOperation(value = "Delete user", notes = "Id will preach", httpMethod = "POST")
	public String deleteUser(@ApiParam(name = "id", value = "User id", required = true) Long id) {
		userDao.deleteUser(id);
		return "{code:0,msg:'success'}"; }}Copy the code

5. Test

Visit http://127.0.0.1:8080/swagger-ui.html for interface test online

Swagger

1.@Api

For a class that identifies this class as a swagger resource. The attributes are as follows:

  • Tags represent instructions, and if tags have multiple values, they generate multiple lists
  • Value indicates a description. You can use tags instead

2.@ApiOperation

Used for methods that represent an HTTP request operation. The attributes are as follows:

  • Value is used for method description
  • Notes is used to prompt content
  • Tags are a list of tags controlled by API documents, as appropriate, and can be grouped independently

3.@ApiParam

For method, parameter, field description; Represents the addition of metadata to the parameter.

  • The name parameter,
  • Value Parameter Description
  • Required Indicates whether this parameter is mandatory

4.@ApiModel

For classes, the class is specified, and for parameters accepted by the entity class.

  • The value object name
  • The description described

5.@ApiModelProperty

Used for methods and fields that represent changes to model properties or data manipulation.

  • Value Field Description
  • Name Specifies the name of the overwrite attribute
  • DataType override attribute dataType
  • Required Indicates whether this parameter is mandatory
  • 1. In fact, it’s a good example.
  • Hidden hidden

6.@ApiIgnore

Used for classes, methods, and method arguments to indicate that the method or class is ignored and not displayed on swagger-ui.html.

7.@ApiImplicitParam

Used for methods that represent individual request parameters.

  • The name parameter,
  • Value Parameter Description
  • DataType dataType
  • ParamType Parameter type
  • 1. In fact, it’s a good example.

8.@ApiImplicitParams

For methods, containing multiple @apiIMPLicitParam.

9.@ApiResponses @ApiResponse

Used of a class or method that describes possible responses to an operation.

  • Code Indicates the HTTP status code of the response
  • Message The readable message attached to the response

10.@ResponseHeader

For method, response header Settings.

  • Name Name of the response header
  • The description first describe
  • Response The default response class void
  • ResponseContainer is configured according to ApiOperation

Swagger exports the offline API document

1. Export the AsciiDocs, Markdown, and Confluence formats

Add the dependent

<! <dependency> <groupId> IO. Github. Swagger2markup </groupId> < artifactId > swagger2markup < / artifactId > < version > 1.3.3 < / version > < / dependency >Copy the code

Conversion utility class

public class SwaggerUtils {

	private static final String url = "http://127.0.0.1:8080/v2/api-docs"; @throws MalformedURLException */ public static void generateAsciiDocs() throws MalformedURLException { Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.ASCIIDOC) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema().build(); Swagger2MarkupConverter.from(new URL(url)) .withConfig(config) .build() .toFolder(Paths.get("./docs/asciidoc/generated")); * @throws MalformedURLException */ public static void generateAsciiDocsToFile() throws MalformedURLException { Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.ASCIIDOC) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL(url)) .withConfig(config) .build() .toFile(Paths.get("./docs/asciidoc/generated/all")); @throws MalformedURLException */ public static void generateMarkdownDocs() throws MalformedURLException { Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.MARKDOWN) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL(url)) .withConfig(config) .build() .toFolder(Paths.get("./docs/markdown/generated")); } / * * * generate Markdown document format, and rolled into a file * @ throws MalformedURLException * / public static void generateMarkdownDocsToFile () throws MalformedURLException { Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.MARKDOWN) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL(url)) .withConfig(config) .build() .toFile(Paths.get("./docs/markdown/generated/all")); @throws MalformedURLException */ public static void generateConfluenceDocs() throws MalformedURLException { Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS)  .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL(url)) .withConfig(config) .build() .toFolder(Paths.get("./docs/confluence/generated")); } / * * * generate Confluence was format document, and rolled into a file * @ throws MalformedURLException * / public static void generateConfluenceDocsToFile () throws MalformedURLException { Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS)  .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL(url)) .withConfig(config) .build() .toFile(Paths.get("./docs/confluence/generated/all")); }}Copy the code

Using test Controller

@RestController
@RequestMapping("/export")
@ApiIgnore
public class ExportController {

	
	@RequestMapping("/ascii")
	public String exportAscii() throws MalformedURLException{
		SwaggerUtils.generateAsciiDocs();
		return "success";
	}
	
	@RequestMapping("/asciiToFile")
	public String asciiToFile() throws MalformedURLException{
		SwaggerUtils.generateAsciiDocsToFile();
		return "success";
	}
	
	@RequestMapping("/markdown")
	public String exportMarkdown() throws MalformedURLException{
		SwaggerUtils.generateMarkdownDocs();
		return "success";
	}
	
	@RequestMapping("/markdownToFile")
	public String exportMarkdownToFile() throws MalformedURLException{
		SwaggerUtils.generateMarkdownDocsToFile();
		return "success";
	}
	
	@RequestMapping("/confluence")
	public String confluence() throws MalformedURLException{
		SwaggerUtils.generateConfluenceDocs();
		return "success";
	}
	
	@RequestMapping("/confluenceToFile")
	public String confluenceToFile() throws MalformedURLException{
		SwaggerUtils.generateConfluenceDocsToFile();
		return "success"; }}Copy the code

2. Export HTML, PDF, and XML files

Add the dependent

<! - offline document -- -- > < the dependency > < groupId > org. Springframework. Restdocs < / groupId > < artifactId > spring - restdocs - mockmvc < / artifactId >  <scope>test</scope> </dependency> <! <dependency> <groupId> IO. Springfox </groupId> < artifactId > springfox - staticdocs < / artifactId > < version > 2.6.1 < / version > < / dependency >Copy the code
<build> <pluginManagement> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>io.github.swagger2markup</groupId> < artifactId > swagger2markup -- maven plugin < / artifactId > < version > 1.3.1 < / version > < configuration > < swaggerInput > http://127.0.0.1:8080/v2/api-docs < / swaggerInput > < outputDir >. / docs/asciidoc/generated < / outputDir > < config >  <swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage> </config> </configuration> </plugin> <plugin> < the groupId > org. Asciidoctor < / groupId > < artifactId > asciidoctor maven - plugin < / artifactId > < version > 1.5.3 < / version > <! - < version > 2.0.0 - RC. 1 < / version > -- > <! -- Include Asciidoctor PDFforpdf generation --> <dependencies> <dependency> <groupId>org.asciidoctor</groupId> < artifactId > asciidoctorj - PDF < / artifactId > < version > 1.5.0 - alpha. 10.1 < / version > < / dependency > < the dependency > < the groupId > org. Engine < / groupId > < artifactId > works - complete < / artifactId > < version > 1.7.21 < / version > < / dependency > </dependencies> <configuration> <sourceDirectory>./docs/asciidoc/generated</sourceDirectory> <outputDirectory>./docs/asciidoc/html</outputDirectory> <backend>html</backend> <! -- <outputDirectory>./docs/asciidoc/pdf</outputDirectory> <backend>pdf</backend> --> <headerFooter>true</headerFooter> 
						<doctype>book</doctype> 
						<sourceHighlighter>coderay</sourceHighlighter> <attributes> <! Menu bar on the left --> <toc>left</ TOC > <! 3</toclevels> <! --> <sectnums>true</sectnums>
						</attributes>
					</configuration>					
				</plugin>
			</plugins>
		</pluginManagement>

	</build>

Copy the code

Asciidoctor :process-asciidoc can be exported using the MVN asciidoctor:process-asciidoc

<outputDirectory>./docs/asciidoc/html</outputDirectory> 
						<backend>html</backend>
Copy the code

Run the MVN asciidoctor:process-asciidoc command and then the MVN generate-resources command to generate an XML file in the targt/generated-docs directory.

The complete code

github

Yards cloud

The copyright of this article belongs to Chaowu And Qinghan, please indicate the source.

Spring Boot 2.x (15) : Integrate Swagger2 Development API Documentation (Online + Offline)

The original address: https://www.zwqh.top/article/info/24

If the article is helpful to you, please scan the code to pay attention to my public number, the article continues to update…