前言
Swagger是一套开源的API工具包,它已经帮助数百万API开发人员、团队和组织交付了出色的API。
官网:https://swagger.io/
最近工作中需要把swagger从2.0升级到3.0,特此记录下研究和学习实践过程。
因为目前OpenAPI specification已经是V3.0版本的规范(也就是SwaggerV2.0规范),此次主要是将根据该定义生成model class以及swagger的展示,即OAS 3.0的实现进行升级(swagger2.0是基于 The Apache License, Version 2.0许可的OAS3.0实现)。
Swagger Editor
Swagger Editor是一个在Swagger 规范中设计、定义和文档化 restful api的开源编辑器。
网址:https://editor.swagger.io/
Swagger codegen
可以根据swagger editor中描述的OAS(OpenAPI Specification) 自动生成相关的OAS specification以及server stub。
在项目中使用maven plugin
<dependencies>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.codegen.v3</groupId>
<artifactId>swagger-codegen</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.swagger.codegen.v3</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<executions>
<execution>
<id>demo</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${OAS 3.0定义的yml文件目录}</inputSpec>
<templateDirectory>${project.basedir}/../config/template</templateDirectory>
<language>java</language>
<library>jersey2</library>
<output>${project.basedir}</output>
<generateModels>true</generateModels>
<modelPackage>${生成的model class资源的包目录}</modelPackage>
<addCompileSourceRoot>true</addCompileSourceRoot>
<configOptions>
<sourceFolder>${生成的资源的项目目录}</sourceFolder>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
运行maven build后生成的class:
Jersey集成
maven import
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2</artifactId>
</dependency>
spring boot 配置类:
private void configureSwagger(ServletConfig servletConfig) {
register(ApiFacade.class);//资源接口类
register(ApiListingResource.class);
register(OpenApiResource.class);
register(AcceptHeaderOpenApiResource.class);
register(SwaggerSerializers.class);
OpenAPI oas = new OpenAPI();
Info info = new Info()
.title("Demo")
.version("1.0.0")
.description("Demo")
.termsOfService("https://www.xx.com/xxx/legalnotice/")
.contact(new Contact()
.name("API Support Team")
.email("api.query@sc.com")
.url("https://www.xx.com"))
.license(new License()
.name("Company Licence")
.url("http://www.xx.com/licenses/LICENSE-xx.html"));
oas.info(info);
oas.servers(Arrays.asList(new Server().url("https://api.xxx.com/openapi")));
SwaggerConfiguration oasConfig = new SwaggerConfiguration()
.openAPI(oas)
.prettyPrint(true)
.resourcePackages(Stream.of("com.scb.s2b.api.openapi")
.collect(Collectors.toSet()));
try {
new JaxrsOpenApiContextBuilder()
.servletConfig(servletConfig)
.application(this)
.openApiConfiguration(oasConfig)
.buildContext(true);
} catch (OpenApiConfigurationException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
ApiFacade为APIs的实现类,其接口为:
public interface Api {
@POST
@Path("/v2/initiate")
@Consumes({"application/json"})
@Produces({"application/json"})
@Operation(summary = "Demo Initiation",
description = "<p>The Demo API exposes the ability to initiate ...</p>",
responses = {
@ApiResponse(responseCode = "200", description = "Success with data", content = @Content(mediaType = "application/json", examples={@ExampleObject(value = " {\n" +
" \"feild_1\": \"Q4594051\",\n" +
" \"feild_2\": \"20181018OPENAPI1X3ODEU1111111\",\n" +
" \"feild_3\": \"INTERNAL1234567893\",\n" +
" }\n")}, schema = @Schema(implementation = OpenApiPaymentId.class))),
@ApiResponse(responseCode = "201", description = "Success. Data created", content = @Content(schema = @Schema(implementation = Void.class))),
@ApiResponse(responseCode = "202", description = "Success. Data accepted", content = @Content(schema = @Schema(implementation = Void.class))),
@ApiResponse(responseCode = "204", description = "Success. No data returned", content = @Content(schema = @Schema(implementation = Void.class))),
@ApiResponse(responseCode = "400", description = "Invalid request. Missing or invalid data", content = @Content(schema = @Schema(implementation = Void.class))),
@ApiResponse(responseCode = "401", description = "Unauthorised request", content = @Content(schema = @Schema(implementation = Void.class))),
@ApiResponse(responseCode = "403", description = "Authentication failed", content = @Content(schema = @Schema(implementation = Void.class))),
@ApiResponse(responseCode = "404", description = "Resource not found", content = @Content(schema = @Schema(implementation = Void.class))),
@ApiResponse(responseCode = "429", description = "Default return code for health status, indicating a warning", content = @Content(schema = @Schema(implementation = Void.class))),
@ApiResponse(responseCode = "500", description = "Internal server error. This indicates an error in the API server", content = @Content(schema = @Schema(implementation = Void.class))),
@ApiResponse(responseCode = "503", description = "System dependency is down or undergoing maintenance. Try again later", content = @Content(schema = @Schema(implementation = Void.class)))
},
extensions = @Extension(properties = {
@ExtensionProperty(name = "x-markets", value = "CN,US"),
}),
tags = {"Tags Initiation"})
Response xxxInitiate(@ApiParam(value = "") @HeaderParam("PreVerified") String preVerified
, @ApiParam(value = "") @Valid OpenApiInstruction body);
}
Swagger-ui
无需本地运行后台实现逻辑, swagger ui使用swagger codegen生成的OpenAPI specification自动通过浏览器实现可视化。
maven import
<dependency>
<groupId>org.webjars</groupId>
<artifactId>swagger-ui</artifactId>
</dependency>
将引入的swagger-ui.jar中的资源index.html复制到springboot项目的资源路径下:
并修改引入的图片、脚本的路径以及url,也可以根据自己的需求修改其他配置。
例如,启动项目后发现OAS中定义的extensions无法显示,显示顺序不理想,修改这个html文件:
修改完毕,重启后效果:
swagger ui 解析API接口以及model class主要根据其上的annotation,swagger codegen生成的model class支持swagger annotation V 2.0,即,swagger V3.0规范。swagger parser、swagger jax-rs以及swagger ui亦为V2.0,可以解析swagger v2 annotation为swagger openapi 实例,最后生成swagger.json进行展示。