preface
With the evolution of project architecture, the separation of front and back ends is an irresistible trend. One of the problems encountered in practice with this mode of collaboration is documentation.
In “A CTO Told me I needed at least three types of documentation in my project,” we described the importance of documentation, and interface documentation is one of them, and is essential.
But interface documentation is a challenge for developers, and interfaces are constantly changing, and it takes effort to keep interface documentation up to date.
Since there is a pain point, there must be a product to solve this pain point, which is Swagger, which has been updated to Swagger3 version. If you are still stuck in Swagger2, upgrade to Swagger3, the overall UI style and interaction is much more friendly.
This article will focus on Swagger3’s integration with SpringBoot and offline document generation.
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
Pain points Swagger addresses
The traditional way of providing documentation has the following pain points:
- The interface is numerous, the implementation details are complex, and the documentation is laborious and requires continuous maintenance.
- Interface documents need to be synchronized over time;
- Interface return result is not clear, have to construct return structure, etc.;
- You can’t directly test the interface online and often need additional tools such as PostMan.
When Swagger is introduced, the above pain points are easily solved and the following advantages are also brought:
- Timeliness (after the interface is changed, the front and back end personnel can see the latest version in real time)
- Normative (interface specific unified style, such as interface address, request mode, parameters, response format, error message, etc.)
- Consistency (The interface information is consistent and does not differ due to the interface document version)
- Testability (can be tested directly based on interface documentation)
The change of Swagger3
Swagger3.0 changes are summarized in the official document as follows:
- Removed springfox-Swagger2 dependency;
- Delete all @enablesWagger2… Annotations;
- Added the Springfox-boot-starter dependency;
- Remove third-party dependencies such as Guava;
- Document access address is changed to http://ip:port/project/swagger-ui/index.html.
Let’s use it in real combat.
SpringBoot integration Swagger3
SpringBoot integrates Swagger3 in the same way that SpringBoot integrates other frameworks, including importing dependencies, specifying configuration files, creating configuration classes, and using Swagger3.
Introduction of depend on
Introduce Swagger3 dependency in pom.xml of SpringBoot project:
< the dependency > < groupId > IO. Springfox < / groupId > < artifactId > springfox - the boot - starter < / artifactId > < version > 3.0.0 < / version > </dependency>Copy the code
Specifying a configuration file
Generally speaking, Swagger can only be turned on in development or test environments, but must be turned off in production environments. Swagger on/off can be configured in application.properties:
# production environment should be set to false springfox. Documentation. The swagger - UI. Enabled = trueCopy the code
The configuration class
Enable the use of Swagger with the @enableOpenAPI annotation, and configure the general parameters of Swagger in the configuration class.
@configuration @enableOpenAPI Public Class Swagger3Config {@bean public Docket createRestApi() {// Return document abstract message return new Docket(DocumentationType.OAS_30) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.withMethodAnnotation(Operation.class)) .paths(PathSelectors.any()) .build() .globalRequestParameters(getGlobalRequestParameters()) .globalResponses(HttpMethod.GET, getGlobalResponseMessage()) .globalResponses(HttpMethod.POST, getGlobalResponseMessage()); } /** * Generate interface information, */ private ApiInfo ApiInfo () {return new ApiInfoBuilder().title("Swagger3 API documentation ").description(" WeChat: Zhuan2quan "). Contact (new contact (" two seniors ", "https://www.choupangxia.com/", "[email protected]")). The version (" 1.0 "). The build (); } / encapsulation global general parameters * * * * / private List < RequestParameter > getGlobalRequestParameters () {List < RequestParameter > parameters = new ArrayList<>(); Parameters.add (new RequestParameterBuilder().name(" uUID ").description(" device UUID ").required(true) .in(ParameterType.QUERY) .query(q -> q.model(m -> m.scalarModel(ScalarType.STRING))) .required(false) .build()); return parameters; } /** * private List<Response> getGlobalResponseMessage() {List<Response> responseList = new ArrayList<>(); Responselist.add (new ResponseBuilder().code("404").description(" not found ").build()); return responseList; }}Copy the code
The above configuration has completed the integration of Spring Boot and Swagger. The following shows how to use it in business logic.
Use in business
Create two entity classes Goods and CommonResult.
Goods categories:
@apiModelProperty (" ApiModelProperty ") public class Goods {/** * ApiModelProperty(" ApiModelProperty ") Long goodsId; /** * @apiModelProperty (" ApiModelProperty ") private String goodsName; /** * @apiModelProperty (" API ") private BigDecimal price; // omit getter/setter}Copy the code
CommonResult class:
@apiModel ("API ") public class Result<T> {/** * ApiModel("API ") public class Result<T> {/** * Non-0 indicates error ") private Integer code; @apiModelProperty (" error description ") private String MSG; @apiModelProperty (" ApiModelProperty ") private T data; public CommonResult(Integer status, String msg, T data) { this.code = status; this.msg = msg; this.data = data; } public static <T> CommonResult<T> success(T data) {return new CommonResult<>(0, "CommonResult ", data); } public static <T> CommonResult<T> success(Integer code, String msg) { return new CommonResult<>(code, msg, null); } public static <T> CommonResult<T> error(int code, String MSG) {return new CommonResult<>(code, MSG,); null); } // omit getter/setter}Copy the code
Use Swagger API for Controller layer interface.
GoodsController class:
@API (tags = "commodity info Management interface ") @restController @RequestMapping("/goods") Public Class GoodsController {@Operation(summary = @getMapping ("/findGoodsById") public CommonResult<Goods> findGoodsById(@parameter (description = "product ID, positive integer ") @RequestParam(value = "goodsId", required = false, DefaultValue =" 0") Integer goodsId) {system.out.println (" query item details based on item ID=" + goodsId + "); Goods goods = new Goods(); goods.setGoodsId(1L); Goods.setgoodsname (" notebook "); goods.setPrice(new BigDecimal(8888)); return CommonResult.success(goods); }}Copy the code
OrderController class:
@API (tags = "Order Management Interface ") @restController @requestMapping ("/ Order ") Public Class OrderController {@Operation(summary = PostMapping("/order") @apiimplicitparams ({@apiimplicitparam (name = "userId", value = "userId", DataTypeClass = long. class, paramType = "query", example = "123"), @apiIMPLicitParam (name = "goodsId", value = "commodity ID ", dataTypeClass = Integer.class, paramType = "query", example = "1") }) public CommonResult<String> toBuy(@ApiIgnore @RequestParam Map<String, String> params) { System.out.println(params); return CommonResult.success("success"); }}Copy the code
Display effect
To complete the integration, start the SpringBoot project at the access address:
http://127.0.0.1:8080/swagger-ui/index.html
Copy the code
The overall effect can be seen as follows:
Specific commodity information management interface, you can see the request parameters, returned result data structure and other information, click “Try it out”, you can input parameter request parameters, call the interface:
The result of the call is returned:
You can also see the corresponding returned result data and the entity class information annotated by Swagger in the Schemas at the bottom.
Swagger3 Notes Usage Instructions
Now that we know how most of the apis are used, let’s summarize the functions of the related apis:
Tags =" indicates the purpose of the class. You can see the comment "value=" on the UI. This parameter is meaningless, it is also seen on the UI, so no configuration is required. Value =" Notes =" Remarks to the method "@APIIMPLICITParams: Indicates a set of parameters for the requested method. @APIIMPLICITParam: Indicates the parameters for the requested method. Used in the @apiIMPLICITParams annotation to specify aspects of a request parameter Name: parameter name value: Parameter description required: Whether the parameter must be passed paramType: · Header --> retrieve request parameters: @requestheader · query --> retrieve request parameters: @requestParam · path (for restful interfaces) --> retrieve request parameters: @pathVariable · Body (not commonly used) · Form (not commonly used) dataType: parameter type, default String, other values dataType="Integer" defaultValue: Parameter default @APIresponses: Code: a number, such as 400 message: a message, such as "request parameters not filled in" response: The class that throws the exception @apiModel: Used on response classes to represent a message that returns response data (this is typically used in post creation scenarios such as @requestBody where the request parameters cannot be described using the @APIIMPLICITParam annotation) @APIModelProperty: Used of attributes to describe the attributes of the response classCopy the code
Exporting an Offline Document
Swagger provides us with handy online documentation support, but there are some scenarios where we need to provide interface documentation to our collaborators instead of just giving them an address. At this point, we need to export the interface document as an offline document.
Here we integrate the enhanced document KNIfe4J to export offline documents.
Add the KNIfe4J dependency
Add the KNIfe4J dependency to pom.xml:
<dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> The < version > 3.0.2 < / version > < / dependency >Copy the code
Start the knife4j
Add the @enableknife4j annotation to Swagger3Config where Swagger is configured to EnableKnife4j enhancements.
@EnableKnife4j
@Configuration
@EnableOpenApi
public class Swagger3Config {
// ...
}
Copy the code
At this point, if still visit http://localhost:8080/swagger-ui/index.html will find showed no change. Here we need to visit http://localhost:8088/doc.html.
The entire project source code address: github.com/secbr/sprin…
Display effect
When you launch your project and access doc.html, you’ll see that the document style is now pretty cool. Here are some of the renderings:
In the column of “Offline Documents”, you can see four forms of offline document download: Markdown, HTML, Word and OpenAPI.
I feel that the HTML format of the document is more bold, but also more convenient to view, to a picture to see the effect.
summary
Documentation is a must in a project, but with the development of open source frameworks, the pain point of documentation for technical people is gradually being resolved. If you’re still writing documents by hand, you can really try this more user-friendly presentation.
Only by exploring new things and trying new things can we grow faster and have more Plan B.
About the blogger: Author of the technology book SpringBoot Inside Technology, loves to delve into technology and writes technical articles.
Public account: “program new vision”, the blogger’s public account, welcome to follow ~
Technical exchange: Please contact the weibo user at Zhuan2quan