openApi3 规范及knife4j使用

理解 OpenAPI3 及使用

OpenAPI 3,也被称为OpenAPI规范(OpenAPI Specification,OAS),起源于Swagger 2.0规范,提供一个标准的、与具体编程语言无关的 RESTful API 描述规范

项目中使用 Swagger 来自动生成 RESTful API 的接口文档,对于配置项 SwaggerConfiguration 之前都是 CV ,但关于每一项配置的含义都是一知半解,本文通过 Swagger EditorOpenAPI规范 理解清楚常用配置项的含义。

基于springboot2.x + OpenAPI3,使用Knife4j 来自动生成接口文档,依赖引入

xml 复制代码
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
    <version>4.3.0</version>
</dependency>

Info 对象

通过 OpenAPI3 info 对象设置接口文档的基本信息,info 对象:

字段名 类型 描述
title string 必选. 应用的名称。
description string 对应用的简短描述。可以被用来表示富文本呈现。
termsOfService string 指向服务条款的URL地址,必须是URL地址格式。
contact 对象 所开放的API的联系人信息。
license 对象 所开放的API的证书信息。
version string 必选 . API文档的版本信息(注意:这个版本和开放API规范版本没有任何关系)。

Contact 对象:

字段名 类型 描述
name string 人或组织的名称。
url string 指向联系人信息的URL地址,必须是URL地址格式。
email string 人或组织的email地址,必须是email地址格式。

License 对象:

字段名 类型 描述
name string 必选. API的证书名。
url string 指向API所使用的证书的URL地址,必须是URL地址格式。

配置项如下:

yml 复制代码
openapi: "3.0.2"
info:
  title: openAPI Demo
  description: "This is an API program for teaching"
  version: '1.1'
  termsOfService: "https://openapi.apifox.cn/"
  contact:
    name: "api developer"
    url: "http://myblog.cn"
    email: "[email protected]"
  license:
    name: "Apache 2.0"
    url: "http://springdoc.org"
paths: {}

SwaggerConfiguration 配置项

java 复制代码
package com.auth.cloud.swagger.config;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 *
 * @author 
 * @date 2024/02/27
 */
@AutoConfiguration
@ConditionalOnClass({OpenAPI.class})
@EnableConfigurationProperties(SwaggerProperties.class)
@ConditionalOnProperty(prefix = "springdoc.api-docs", name = "enabled", havingValue = "true", matchIfMissing = true)
public class SwaggerConfiguration {

    // ========== 全局 OpenAPI 配置 ==========
    @Bean
    public OpenAPI createOpenApi(SwaggerProperties swaggerProperties) {
        System.out.println("SwaggerAutoConfiguration.createOpenApi()"+swaggerProperties);
        return new OpenAPI()
                .info(buldInfo(swaggerProperties))
                ;
    }

    public Info buldInfo(SwaggerProperties swaggerProperties) {
        return new Info()
                .title(swaggerProperties.getTitle())
                .description(swaggerProperties.getDescription())
                .version(swaggerProperties.getVersion())
                .termsOfService(swaggerProperties.getTermsOfService())
                .contact(new Contact().name(swaggerProperties.getAuthor()).email(swaggerProperties.getEmail()).url(swaggerProperties.getUrl()))
                .license(new License().name(swaggerProperties.getLicense()).url(swaggerProperties.getLicenseUrl()));
    }
}

效果图如下:

servers 对象

servers 主要表示访问服务端的基础路径,既在访问接口前都会带上该参数,无需手动配置,示例如下:

Paths 对象

paths 对象包含真正的 API 信息内容,定义各个的端点和操作的相对路径,自动生成。

字段名模式 类型 描述
/{path} Path Item 对象 到各个端点的相对路径,路径必须以/打头,这个路径会被直接连接Server 对象url字段以组成完整URL地址(不会考虑是否是相对路径)。这里可以使用 Path templating ,当做URL地址匹配时,不带路径参数的路径会被优先匹配。应该避免定义多个具有相同路径层级但是路径参数名不同的路径,因为他们是等价的。当匹配出现歧义时,由使用的工具自行决定使用那个路径。

以下是目前会用到的所有关于接口文档的注解

java 复制代码
import com.auth.cloud.common.pojo.CommonResult;

import com.auth.cloud.i18n.core.I18n;
import com.auth.cloud.permission.service.RoleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;


/**
 * @author 
 * @date 2024/01/03
 */
@RestController
@RequestMapping("/role")
@Slf4j
@Validated
@Tag(name = "权限管理后台 - 角色", description = "角色信息接口")
public class RoleController {

    @Autowired
    private I18n i18n;

    @Autowired
    private RoleService roleService;

    @GetMapping("/{id}")
    @Operation(summary = "测试接口",description = "测试接口参数")
    @Parameters({
            @Parameter(name = "id", description = "文件id", in = ParameterIn.PATH),
            @Parameter(name = "token", description = "请求token", required = true, in = ParameterIn.HEADER),
            @Parameter(name = "name", description = "文件名称", required = true, in = ParameterIn.QUERY)
    })
    public CommonResult<String> test(@PathVariable("id") String id, @RequestHeader("token") String token,
                                         @RequestParam("name") String name) {
        return CommonResult.success("name" + name + "id" + id + "token" + token);
    }
}

配置项如下:

yml 复制代码
paths:
  '/role/{id}':
    get:
      tags:
        - 权限管理后台 - 角色
      summary: 测试接口
      description: 测试接口参数
      operationId: test
      parameters:
        - name: id
          in: path
          description: 文件id
          required: true
          schema:
            type: string
        - name: token
          in: header
          description: 请求token
          required: true
          schema:
            type: string
        - name: name
          in: query
          description: 文件名称
          required: true
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/CommonResultString'
components:
  schemas:
    CommonResultString:
      type: object
      properties:
        code:
          type: integer
          format: int32
        msg:
          type: string
        data:
          type: string

以上信息描述一个 /role/{id} 的接口 ,它只包含一个 get 操作对象,也称 Operation 对象,属性包含以下:

字段名 类型 描述
tags [string] 用于控制API文档的标签列表,标签可以用于在逻辑上分组
summary string 对此操作行为的简短描述。
description string 对此操作行为的详细解释。
operationId string 用于标识此操作的唯一字符串,即方法名。
parameters [Parameter 对象 | Reference 对象] 定义可用于此操作的参数列表,如果一个同名的参数已经存在于 Path Item,那么这里的定义会覆盖它但是不能移除上面的定义。这个列表不允许包含重复的参数,参数的唯一性由 namelocation 的组合来确定。这个列表可以使用 Reference 对象 来连接定义于 OpenAPI 对象 components/parameters 的参数。
responses Responses 对象 必选. 定义执行此操作后的可能的响应值列表。
security [Security Requirement 对象] 声明哪种安全机制可用于此操作。这个列表可以包含多种可用于此操作的安全需求对象,但是在认证一个请求时应该仅使用其中一种。这里的定义会覆盖任何在顶层 security 中的安全声明,因此可以声明一个空数组来变相的移除顶层的安全声明。

parameters:该接口的请求参数对象,描述如下:

  • name:参数名称

  • in:参数出现的位置,通常是 headerpathquerycookie

  • description:参数的描述(支持 markdown)

  • required:必填项

  • deprecated:是否弃用

  • allowEmptyValue:允许提交空值

  • style:参数序列化方式

  • explode:与数组相关的参数

  • schema:参数的模型

  • example:媒体类型的示例

Response :描述单个API操作的响应,描述如下:

字段名 类型 描述
description string 必选 . 对响应的简短描述。CommonMark syntax可以被用来呈现富文本格式.
headers Map[string, Header 对象 | Reference 对象] 映射HTTP头名称到其定义。RFC7230 规定了HTTP头名称不区分大小写。如果一个响应头使用"Content-Type"作为HTTP头名称,它会被忽略。
content Map[string, Media Type 对象] 一个包含描述预期响应负载的映射。使用 media type 或 media type range 作为键,以响应的描述作为值。当一个响应匹配多个键时,只有最明确的键才适用。比如:text/plain 会覆盖 text/*

security 对象

大部分的 Web 服务都是需要经过身份认证的才能访问,security 就是用于描述 API 的安全信息和访问授权协议等信息的对象,该属性定义可以放在 Paths 对象的 Operation 对象中,在可在 OpenAPI 文档的根目录添加安全对象,两者的区别如下:

Security Requirement 对象

每个属性的名字都必须与Components 对象Security Schemes 声明的 security scheme 相符。

字段名模式 类型 描述
{name} [string] 每个名称都必须对应于 Components 对象 下的 Security Schemes 的一个 security scheme。如果此 security scheme 是 "oauth2""openIdConnect" 类型,那么其值是用于执行的一组 scope names。对于其他 security scheme 类型。此数组必须是空的。

Security Requirement 对象示例

Non-OAuth2 Security Requirement

json 复制代码
{
  "api_key": []
}
api_key: []

OAuth2 Security Requirement

json 复制代码
{
  "petstore_auth": [
    "write:pets",
    "read:pets"
  ]
}
petstore_auth:
- write:pets
- read:pets

Security Scheme 对象

固定字段

字段名 类型 Applies To 描述
type string Any 必选 . security scheme 的类型。有效值包括 "apiKey", "http", "oauth2", "openIdConnect".
description string Any 对 security scheme 的简短描述. CommonMark syntax可以被用来呈现富文本格式.
name string apiKey 必选. 用于 header、 query 或 cookie 的参数名字。
in string apiKey 必选 . API key 的位置。有效值包括 "query""header""cookie".
scheme string http 必选 . 用于 Authorization header as defined in RFC7235 的 HTTP Auahorization scheme 的名字.
bearerFormat string http ("bearer") 用于提示客户端所使用的bearer token的格式。Bearer token 通常通过一个authorization server生成,所以这个字段最主要的目的是用来记录这个信息。
flows OAuth Flows 对象 oauth2 必选. 一个包含所支持的 flow types 的配置信息的对象。
openIdConnectUrl string openIdConnect 必选. 用于发现 OAuth2 配置值的OpenId Connect URL,必须是 URL 形式。
java 复制代码
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpHeaders;

import java.util.HashMap;
import java.util.Map;

/**
 * Swagger 自动配置类,基于 OpenAPI + Springdoc 实现。
 *
 * @author 
 * @date 2024/02/27
 */
@AutoConfiguration
@ConditionalOnClass({OpenAPI.class})
@EnableConfigurationProperties(SwaggerProperties.class)
@ConditionalOnProperty(prefix = "springdoc.api-docs", name = "enabled", havingValue = "true", matchIfMissing = true)
public class SwaggerAutoConfiguration {

    // ========== 全局 OpenAPI 配置 ==========
    @Bean
    public OpenAPI createOpenApi(SwaggerProperties swaggerProperties) {
        Map<String, SecurityScheme> securitySchemas = buildSecuritySchemes();
        OpenAPI openAPI = new OpenAPI()
                .info(buldInfo(swaggerProperties))
                // 接口安全配置
                .components(new Components().securitySchemes(securitySchemas))
                .addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION));
        return openAPI;
    }

    /**
     * API 摘要信息
     */
    public Info buldInfo(SwaggerProperties swaggerProperties) {
        return new Info()
                .title(swaggerProperties.getTitle())
                .description(swaggerProperties.getDescription())
                .version(swaggerProperties.getVersion())
                .termsOfService(swaggerProperties.getTermsOfService())
                .contact(new Contact().name(swaggerProperties.getAuthor()).email(swaggerProperties.getEmail()).url(swaggerProperties.getUrl()))
                .license(new License().name(swaggerProperties.getLicense()).url(swaggerProperties.getLicenseUrl()));
    }

    /**
     * 安全模式,这里配置通过请求头 Authorization 传递 token 参数
     */
    private Map<String, SecurityScheme> buildSecuritySchemes() {
        Map<String, SecurityScheme> securitySchemes = new HashMap<>();
        SecurityScheme securityScheme = new SecurityScheme()
                .type(SecurityScheme.Type.APIKEY) // 类型
                .name(HttpHeaders.AUTHORIZATION) // 请求头的 name
                .in(SecurityScheme.In.HEADER); // token 所在位置
        securitySchemes.put(HttpHeaders.AUTHORIZATION, securityScheme);
        return securitySchemes;
    }
}

参考:

OpenAPI 3.0 规范-食用指南

相关推荐
秋野酱1 小时前
基于javaweb的SpringBoot自习室预约系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
weloveut1 小时前
西门子WinCC Unified PC的GraphQL使用手册
后端·python·graphql
不念霉运3 小时前
2025年中国主流DevOps平台对比分析:Gitee、阿里云效与GitLab CE的技术适配与合规实践全景解读
团队开发·代码规范·devops·代码复审
蒂法就是我3 小时前
详细说说Spring的IOC机制
java·后端·spring
秋野酱3 小时前
基于javaweb的SpringBoot高校图书馆座位预约系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
HWL56794 小时前
Express项目解决跨域问题
前端·后端·中间件·node.js·express
-曾牛4 小时前
Spring AI 集成 Mistral AI:构建高效多语言对话助手的实战指南
java·人工智能·后端·spring·microsoft·spring ai
shengjk16 小时前
序列化和反序列化:从理论到实践的全方位指南
java·大数据·开发语言·人工智能·后端·ai编程
hie988947 小时前
使用Spring Boot集成Nacos
java·spring boot·后端
源码方舟7 小时前
基于SpringBoot+Vue的房屋租赁管理系统源码包(完整版)开发实战
vue.js·spring boot·后端