《Techporters架构搭建》-Day07 集成API文档工具

源码地址:请看day07

前言

在现代软件开发中,良好的API文档是团队协作和项目管理中不可或缺的一部分。OpenAPI规范(前身为Swagger)为我们提供了一种标准化的方式来描述和管理RESTful API,Spring Boot通过集成相关工具使得生成和维护API文档变得更加简单和高效。本文将详细介绍如何在Spring Boot项目中利用OpenAPI来自动生成和管理API文档。

API文档化历史

做过API文档化经常可以听到一下几个概念:SwaggerSpringFoxSpringDocOpenAPIKnife4j
1.Swagger2是一组围绕 OpenAPI 规范构建的开源工具,可帮助您设计、构建、记录和使用 REST API。主要的 Swagger 工具包括:

Swagger Editor – 基于浏览器的编辑器,您可以在其中编写 OpenAPI 规范。
Swagger UI – 将 OpenAPI规范呈现为交互式 API 文档。
swagger2于17年停止维护,现在最新的版本为 Swagger3(Open Api3)。

2.Open API
OpenAPI是业界真正的 api 文档标准,其是由 Swagger 来维护的,并被Linux列为api标准,从而成为行业标准,如果想了解
Open API规范,请查看 Swagger EditorOpenAPI规范
3.Swagger3(OpenAPI3)
Swagger 规范已于 2015 年捐赠给 Linux 基金会后改名为 OpenAPI,并定义最新的规范为 OpenAPI 3.0。所以现在的 Swagger 3.0 就是 OpenAPI 3.0。

4.SpringFoxSpringDoc
SpringFox: SpringFox 是一个老牌的库,用于将 Spring Boot 应用程序集成到 Swagger(现在称为 OpenAPI)规范中。它通过使用 Swagger 注解来描述 API,并生成符合 OpenAPI 规范的文档。SpringFox 支持Swagger 2.0 版本以及后续的 OpenAPI 3.0 版本。 SpringFox: 使用 @Api、@ApiOperation 等 Swagger 注解
SpringDoc: SpringDoc是一个相对较新的库,也是用于将 Spring Boot 应用程序集成到 OpenAPI 规范中。它采用更简化的注解,使得在代码中描述 API更为直观。SpringDoc 专注于支持 OpenAPI 3.0 版本。使用 @OpenAPIDefinition、@Operation 等 OpenAPI 注解

5.Knife4j
Knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名kni4j是希望她能像一把匕首一样小巧,轻量,并且功能强悍!(官网)

集成Knife4j

目前只创建了一个微服务,所以本节我们只是在tps-system中添加Knife4j,后续多个微服务后,我们会进行改进,通过网关聚合所有的Swagger微服务文档。
首先,引用Knife4j的starter,在根Gradle下添加版本号及knife4j引入

knife4jVersion='4.4.0'
implementation "com.github.xiaoymin:knife4j-openapi3-jakarta-spring-boot-starter:${knife4jVersion}"

引入之后,要启用Knife4j的增强功能,可以在配置文件中进行开启,knife4j各种配置可以到官网去看看
部分配置如下:

# springdoc-openapi项目配置
springdoc:
  swagger-ui:
    path: /swagger-ui.html
    tags-sorter: alpha
    operations-sorter: alpha
  api-docs:
    path: /v3/api-docs
  group-configs:
    - group: 'default'
      paths-to-match: '/**'
      packages-to-scan: com.tps.cloud.system
# knife4j的增强配置,不需要增强可以不配
knife4j:
  enable: true
  setting:
    language: zh_cn
  basic:
    enable: true
    # Basic认证用户名
    username: system
    # Basic认证密码
    password: 123456 

常用注解

在写代码之前,先了解一下OpenAPI 3.0有哪些注解以及各个注解的作用。

基本信息注解

@OpenAPIDefinition

  • 描述:用于定义整个 API 文档的基本信息。
  • 可用于:类、接口。
  • 属性
    • info:指定 @Info 注解的对象,用于描述 API 文档的基本信息。

@Info

  • 描述:用于定义 API 文档的基本信息。
  • 可用于:类、接口。
  • 属性
    • title:API 的标题。
    • description:API 的描述。
    • version:API 的版本号。
    • termsOfService:服务条款的 URL。
    • contact:指定 @Contact 注解的对象,用于描述联系人信息。
    • license:指定 @License 注解的对象,用于描述许可证信息。

@Contact

  • 描述:用于定义 API 文档中的联系人信息。
  • 可用于:类、接口。
  • 属性
    name:联系人的名称。
    url:联系人的网址。
    email:联系人的电子邮件地址。

@License

  • 描述:用于定义 API 文档中的许可证信息。
  • 可用于:类、接口。
  • 属性
    • name:许可证的名称。
    • url:许可证的网址。

分组注解

@Tag

  • 描述:用于给 API 分组,用途类似于为 API 文档添加标签。
  • 可用于:方法、类、接口。
  • 属性
    • name:分组的名称。

请求方法注解

以下注解用于描述 API 的请求方法:

@Operation

  • 描述:用于描述 API 的操作。
  • 可用于:方法。
  • 属性
    • summary:操作的摘要信息。
    • description:操作的详细描述。
    • tags:指定 @Tag 注解的对象数组,用于将操作归类到特定的分组。
    • parameters:指定 @Parameter 注解的对象数组,用于描述操作的输入参数。
    • responses:指定 @ApiResponse 注解的对象数组,用于描述操作的响应结果。
    • requestBody:指定 @RequestBody 注解的对象,用于描述操作的请求体。

@Parameter

  • 描述:用于描述操作的输入参数。
  • 可用于:方法。
  • 属性
    • name:参数的名称。
    • in:参数的位置,可以是 path、query、header、cookie 中的一种。
    • description:参数的描述。
    • required:参数是否必需,默认为 false。
    • schema:指定 @Schema 注解的对象,用于描述参数的数据类型。

@RequestBody

  • 描述:用于描述操作的请求体。
  • 可用于:方法。
  • 属性:
    • required:请求体是否必需,默认为 false。
    • content:指定 @Content 注解的对象数组,用于描述请求体的内容。

@ApiResponse

  • 描述:用于描述操作的响应结果。
  • 可用于:方法。
  • 属性
    • responseCode:响应的状态码。
      -description:响应的描述。
      -content:指定 @Content 注解的对象数组,用于描述响应的内容。

@Content

  • 描述:用于描述请求体或响应的内容。
  • 可用于:方法。
  • 属性
    • mediaType:内容的媒体类型。
    • schema:指定 @Schema 注解的对象,用于描述内容的数据类型。

@Schema

  • 描述:用于描述数据模型的属性。
  • 可用于:方法、类、接口。
  • 属性
    • title:数据模型的标题。
    • description:数据模型的描述。
    • type:数据模型的类型。
    • format:数据模型的格式。

路径注解

以下注解用于描述 API 的路径:
@Path

  • 描述:用于定义路径参数。
  • 可用于:方法。
  • 属性
    • value:路径参数的名称。

@PathVariable

  • 描述:用于描述路径参数。
  • 可用于:方法的参数。
  • 属性
    • value:路径参数的名称。

@RequestParam

  • 描述:用于描述查询参数。
  • 可用于:方法的参数。
  • 属性
    • value:查询参数的名称。
    • required:查询参数是否必需,默认为 false。

@RequestBody

  • 描述:用于描述请求体。
  • 可用于:方法的参数。

响应注解
以下注解用于描述 API 的响应结果:

@ApiResponse

  • 描述:用于描述响应结果。
  • 可用于:方法。
  • 属性
    • responseCode:响应的状态码。
    • description:响应的描述。
    • content:指定 @Content 注解的对象数组,用于描述响应的内容。

@Content

  • 描述:用于描述响应结果的内容。
  • 可用于:方法。
  • 属性
    • mediaType:内容的媒体类型。
    • schema:指定 @Schema 注解的对象,用于描述内容的数据类型。

@Schema

  • 描述:用于描述数据模型的属性。
  • 可用于:方法、类、接口。
  • 属性
    • title:数据模型的标题。
    • description:数据模型的描述。
    • type:数据模型的类型。
    • format:数据模型的格式。

使用示例

package com.tps.cloud.system.controller;

import com.tps.cloud.group.UpdateGroup;
import com.tps.cloud.response.Result;
import com.tps.cloud.system.dto.SystemUserDto;
import com.tps.cloud.system.service.SystemUserService;
import com.tps.cloud.system.vo.SystemUserVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * 用户管理 前端控制器
 */
@RestController
@AllArgsConstructor
@RequestMapping("/system/users")
@Tag(name = "用户管理", description = "用于管理用户信息")
public class SystemUserController {

    private final SystemUserService systemUserService;

    private final MessageSourceAccessor messages;

    @PostMapping
    @Operation(summary = "创建用户", description = "创建用户")
    public Result<Long> save(@RequestBody @Validated SystemUserDto systemUserDto) {
        //验证用户唯一
        SystemUserVo systemUserVo=systemUserService.findByUsername(systemUserDto.getUsername());
        if(systemUserVo!=null){
            return Result.failed(messages.getMessage("SystemUserDto.Username.Exist"));
        }
        Long id=systemUserService.createUser(systemUserDto);
        return Result.ok(id);
    }

    @PutMapping
    @Operation(summary = "更新用户信息", description = "更新用户信息")
    public Result<Boolean> update(@RequestBody @Validated({UpdateGroup.class}) SystemUserDto systemUserDto) {
        systemUserService.updateUser(systemUserDto);
        return Result.ok(true);
    }

    @GetMapping
    @Operation(summary = "根据ID获取用户信息", description = "根据用户ID查询用户的详细信息")
    @Parameter(name = "id", description = "用户id", required = true)
    public Result<SystemUserVo> getUser(@RequestParam("id") Long id) {
        SystemUserVo user = systemUserService.getUser(id);
        return Result.ok(user);
    }
}
package com.tps.cloud.system.dto;

import com.tps.cloud.group.AddGroup;
import com.tps.cloud.group.UpdateGroup;
import com.tps.cloud.system.constraint.UniqueUsername;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;

import java.time.LocalDateTime;

/**
 * 用户信息传输类
 */
@Data
public class SystemUserDto  {
    /**
     * 用户id
     */
    @Schema(description = "用户id")
    private Long id;
    /**
     * 用户账号
     */
    @NotBlank(message = "{SystemUserDto.Username.NotEmpty}")
    //@UniqueUsername
    @Schema(description = "用户账号")
    private String username;
    /**
     * 密码
     */
    @NotBlank(message = "密码不能为空",groups = {AddGroup.class,UpdateGroup.class})
    @Schema(description = "密码")
    private String password;
    /**
     * 用户昵称
     */
    @Schema(description = "用户昵称")
    private String nickname;
    /**
     * 备注
     */
    @Schema(description = "备注")
    private String remark;
    /**
     * 部门id
     */
    @Schema(description = "部门id")
    private Long deptId;
    /**
     * 用户邮箱
     */
    @Schema(description = "用户邮箱")
    private String email;
    /**
     * 手机号码
     */
    @Schema(description = "手机号码")
    private String mobile;
    /**
     * 用户性别
     */
    @Schema(description = "用户性别")
    private Integer sex;
    /**
     * 头像地址
     */
    @Schema(description = "头像地址")
    private String avatar;
    /**
     * 帐号状态(0正常 1停用)
     */
    @Schema(description = "帐号状态")
    private Integer status;
    /**
     * 最后登录IP
     */
    @Schema(description = "最后登录IP")
    private String loginIp;
    /**
     * 最后登录时间
     */
    @Schema(description = "最后登录时间")
    private LocalDateTime loginDate;

    /**
     * 部门
     */
    @Valid
    @Schema(description = "部门")
    private SystemDeptDto systemDept;
}

重新启动项目,访问http://localhost:8080/doc.html
在这里插入图片描述

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值