文章
问答
冒泡
OpenApiTools 应用

对于管理平台来说,通过确定前期明确需求做出相关设计,为了快速迭代功能接口开发,对于脚手架还是有一定需求的。另外我们习惯通过swagger文档来提供接口文档的描述,最近也是刚接触openapi3,另外发现通过集成openapitools 及swagger 的依赖能够一步到位。

介绍

OpenAPI 规范(OAS)定义了一个标准的、语言无关的 RESTful API 接口规范,它可以同时允许开发人员和操作系统查看并理解某个服务的功能,而无需访问源代码,文档或网络流量检查(既方便人类学习和阅读,也方便机器阅读)。正确定义 OAS 后,开发者可以使用最少的实现逻辑来理解远程服务并与之交互。

此外,文档生成工具可以使用 OpenAPI 规范来生成 API 文档,代码生成工具可以生成各种编程语言下的服务端和客户端代码,测试代码和其他用例。

IDEA 插件推荐

编写 openapis.yaml 文件推荐idea 插件如下:
openapi-plugin.png

Maven 文件配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.kirago.opt</groupId>
    <artifactId>opt-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>opt-demo</name>
    <description>Demo project for openapitools</description>
    <properties>
        <java.version>1.8</java.version>
        <javax.validation-api-version>2.0.1.Final</javax.validation-api-version>
        <swagger-annotations-version>1.5.21</swagger-annotations-version>
        <swagger-models-version>1.5.21</swagger-models-version>
        <springfox-version>2.9.2</springfox-version>
        <jackson-databind-nullable>0.2.1</jackson-databind-nullable>
    </properties>
    <dependencies>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>${swagger-annotations-version}</version>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>${swagger-models-version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${springfox-version}</version>
            <exclusions>
                <exclusion>
                    <groupId>io.swagger</groupId>
                    <artifactId>swagger-annotations</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>io.swagger</groupId>
                    <artifactId>swagger-models</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${springfox-version}</version>
        </dependency>
        <dependency>
            <groupId>org.openapitools</groupId>
            <artifactId>jackson-databind-nullable</artifactId>
            <version>${jackson-databind-nullable}</version>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>${javax.validation-api-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.openapitools</groupId>
                <artifactId>openapi-generator-maven-plugin</artifactId>
                <version>4.3.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                        <!-- openapis.yaml 配置文件位置及生成路径相关配置 -->
                            <inputSpec>${project.basedir}/src/main/resources/openapis.yaml</inputSpec>
                            <generatorName>spring</generatorName>
                            <apiPackage>com.kirago.optd.api</apiPackage>
                            <modelPackage>com.kirago.optd.model</modelPackage>
                            <invokerPackage>com.kirago.optd.invoker</invokerPackage>
                            <modelNamePrefix>Api</modelNamePrefix>
                            <configOptions>
                                <delegatePattern>true</delegatePattern>
                                <configPackage>com.kirago.optd.config</configPackage>
                                <swaggerDocketConfig>true</swaggerDocketConfig>
                            </configOptions>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

openapis.yaml 配置文件描述

openapi: 3.0.1
info:
  title: Sample API For OpenApiTools Demo
  description: API description in Markdown.
  version: 1.0.0

  
servers:
  - url: '{protocol}://{host}:{port}/optd/v1'
    variables:
      protocol:
        enum:
          - http
          - https
        default: http
      host:
        enum:
          - 127.0.0.1
          - localhost
        default: 127.0.0.1
      port:
        enum:
          - '8080'
        default: '8080'
        
tags:
  - name: User
    description: 用户模块

paths:
  /users:
    get:
      tags:
        - User
      summary: 获取用户列表
      description: Optional extended description in Markdown.
      responses:
        '200':
          description: 获取用户列表
          content: 
            application/json:
              schema: 
                type: array
                items: 
                  $ref: '#/components/schemas/UserInfo'
  /user:
    post:
      tags:
        - User
      summary: 添加用户
      description: 添加用户
      operationId: createUser
#      parameters:
#        通过cookie来验证权限
#        - in: cookie
#          name: DEMO-COOKIE
#          schema: 
#            type: string
      requestBody: 
        description: 添加用户
        required: true
        content: 
          application/json:
            schema: 
              $ref: '#/components/schemas/CreateUserRequest'
      responses: 
        '201':
          description: 操作成功
        '400':
          description: 输入参数错误
          content: 
            application/json:
              schema: 
                $ref: '#/components/schemas/ValidationError'
    delete:
      tags:
        - User
      summary: 删除用户
      description: 删除用户
      operationId: deleteUserByName
      parameters:
        - name: userName
          in: path
          required: true
          allowEmptyValue: false
          schema: 
            type: string
      responses: 
        '200':
          description: 删除成功
          
    get:
      tags:
        - User
      description: 根据用户姓名进项查找
      summary: 根据用户姓名进行查找
      operationId: getUserByName
      responses: 
        '200':
          description: user response
          content: 
            'text/json':
              schema: 
                $ref: '#/components/schemas/UserInfo'
    parameters:
      - name: name
        in: path
        description: 根据姓名进行查找
        required: true
        schema: 
          type: string


components: 
  schemas: 
    CreateUserRequest:
      type: object
      properties: 
        name:
          type: string
          description: '姓名'
          example: 张三
        gender:
          type: integer
          description: '性别'
          example: 0
        cif:
          $ref: '#/components/schemas/PhoneNumber'
          
    UserInfo:
      type: object
      properties: 
        name:
          type: string
          description: '姓名'
          example: 张三
        gender:
          type: integer
          description: '性别'
          example: 男
        contact:
          $ref: '#/components/schemas/PhoneNumber'

    PhoneNumber:
      type: integer
      properties: 
        phoneNum:
          type: integer
          description: '电话号码'
          example: 12446487109
    
    ValidationError:
      type: object
      required:
        - code
        - message
        - errors
      properties:
        code:
          type: string
          description: 错误信息码
        message:
          type: string
          description: 错误信息
        errors:
          type: array
          description: 参数错误信息
          items:
            type: string

具体文档请参考:OpenApi-Specification文档
我这里只是做了简单的demo演示,其实当需求明确及接口规范下来之后,我们结合Specification 进行一些schemas的描述就能够将我们的大概脚手架生成出来,剩下的service层或者dao 层的操作这些业务代码我们就自己根据实际业务需求去进行编写。

下面就让我们来进行脚手架代码生成:
这里有个小插曲,我第一次生成代码的时候也是通过如下插件去生成的
image.png
如果不出意外的话会报出如下的错误:
image.png
但是看了下实际的 maven 配置我是配了这个的,此时google一把,解决方法如下,inSpec Error
老外说到这个报错也比较 trick。
image.png
通过 maven compile 生成的最终代码:
目录结构如下:
image.png
实际上我只做了一个openapis.yaml 的配置就已经将整个工程脚手架搭建起来了,这里对 OpenApi-Specification 文档还是有点要求的,最好能够通读了解下,然后根据自己的需要学习下具体配置的细节,建议一开始通读了解。

Swagger 文档

之前每次写完接口以及在定义model 的时候,我当时都是手动在代码上加注解,然后才在swagger文档上有具体说明的,不知道其他老铁是不是这样的。此次通过此种方式,我们查看下代码:
image.png
我们会发现实际上已经帮我们全部处理掉了,我还是很开心的,少了一堆无营养的操作,试着运行下代码看看结果:
image.png

个人感觉,对于管理平台类的开发此脚手架加上JPA简直就是神器,当然对于service等一些业务强相关的工作这个当然肯定还是需要自己去填充的,可以通过扩展对应的职责类去完成业务逻辑开发,有兴趣的朋友可以尝试下。不过如果想利用一些比较强大的特性还是有必要去看看 Specification 文档的。

示例代码

java
openapi

关于作者

Kirago
个人站点 https://kiragoo.github.io/
获得点赞
文章被阅读