OpenAPITools 能够根据 REST API 形容文件,主动生成服务端桩(Stub)代码、客户端 SDK 代码,及文档等。其是社区版的 Swagger ,差别可见:OpenAPI Generator vs Swagger Codegen。

本文将从零开始设计和编写 API 文件,并生成 Go Gin 服务端代码,与 Python SDK 代码。更多语言或框架,也是一样操作的。

疾速开始

先相熟下工具,间接用官网 Docker 镜像生成 Petstore 样例的 Go SDK 代码:

docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \-i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml \-g go \-o /local/out/go

生成代码在当前目录的 ./out/go

关上 Swagger Editor File > Import URL 查看 petstore.yaml API:

查看 openapi-generator-cli 用法:

docker run --rm -it \-v "${PWD}:/local" \--entrypoint /bin/bash \openapitools/openapi-generator-cliln -s /usr/local/bin/docker-entrypoint.sh /usr/local/bin/openapi-generatoropenapi-generator helpopenapi-generator help generate

入手实际

设计 RESTful API

关上 Swagger Editor 设计 API:

  • /albums

    • GET - Get all albums
    • POST - Create a new album
  • /albums/:id

    • GET - Get an album by its id
    • PUT - Update an album by its id
    • DELETE - Delete an album by its id

残缺 API 形容文件见 spec/api.yaml,次要蕴含三局部:

1 头部: API 信息

openapi: 3.0.0info:  title: Start OpenAPITools  description: Let's practice designing our api.  version: 0.1.0  license:    name: MIT    url: https://spdx.org/licenses/MIT.htmlservers:  - url: https://github.com/ikuokuo/start-openapitools

2 两头: paths 及其操作 (get, post, etc.)

paths:  /albums/{id}:    get:      tags:        - album      summary: Get an album by its id      operationId: getAlbum      parameters:        - $ref: '#/components/parameters/AlbumId'      responses:        200:          description: Get success, return the album          content:            application/json:              schema:                $ref: '#/components/schemas/Album'        404:          description: Album not found

3 底部: 可重用的 components,于文档里 $ref 援用

components:  parameters:    AlbumId:      name: id      in: path      description: Album id      required: true      schema:        type: string  schemas:    Album:      title: Album      type: object      required:        - title        - artist        - price      properties:        id:          type: string          format: uuid        title:          type: string          maxLength: 200          minLength: 1        artist:          type: string          maxLength: 100          minLength: 1        price:          type: number          format: double          minimum: 0.0        created_at:          type: string          format: date-time        updated_at:          type: string          format: date-time

具体阐明,请浏览 OpenAPI Specification。

在线生成代码

能够用线上服务疾速生成代码:

  • latest stable version: https://api.openapi-generator...

以下则是本人入手生成的过程。

生成 Server Stub 代码

生成 Go Gin 桩(Stub)代码:

docker run --rm -it \-v "${PWD}:/local" \--entrypoint /bin/bash \openapitools/openapi-generator-cliln -s /usr/local/bin/docker-entrypoint.sh /usr/local/bin/openapi-generator# Config Options for go-gin-server#  https://openapi-generator.tech/docs/generators/go-gin-serveropenapi-generator config-help -g go-gin-serveropenapi-generator generate \-g go-gin-server \-i /local/spec/swagger.yaml \-o /local/out/gin-server \--additional-properties=packageName=startapi

生成内容:

❯ tree out/gin-server -aF --dirsfirstout/gin-server├── .openapi-generator/├── api/│   └── openapi.yaml├── go/│   ├── README.md│   ├── api_album.go│   ├── api_albums.go│   ├── model_album.go│   └── routers.go├── .openapi-generator-ignore├── Dockerfile└── main.go

简略实现 GetAlbum 接口,位于 go/api_album.go

// GetAlbum - Get an album by its idfunc GetAlbum(c *gin.Context) {    c.JSON(http.StatusOK, Album{        Id:        "3fa85f64-5717-4562-b3fc-2c963f66afa6",        Title:     "Start OpenAPITools",        Artist:    "GoCoding",        Price:     0.99,        CreatedAt: time.Now(),        UpdatedAt: time.Now(),    })}

运行服务:

cd out/gin-server/# 初始化模块go mod init github.com/ikuokuo/start-openapitools/gin-servergo mod tidy# 批改 `main.go` 中的 import 门路#  sw "github.com/ikuokuo/start-openapitools/gin-server/go"# 替换老本地门路go mod edit -replace github.com/ikuokuo/start-openapitools/gin-server/go=./go

运行后果:

❯ go run .2021/11/05 18:20:00 Server started[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env:   export GIN_MODE=release - using code:  gin.SetMode(gin.ReleaseMode)[GIN-debug] GET    /ikuokuo/start-openapitools/ --> github.com/ikuokuo/start-openapitools/gin-server/go.Index (3 handlers)[GIN-debug] DELETE /ikuokuo/start-openapitools/albums/:id --> github.com/ikuokuo/start-openapitools/gin-server/go.DeleteAlbum (3 handlers)[GIN-debug] GET    /ikuokuo/start-openapitools/albums/:id --> github.com/ikuokuo/start-openapitools/gin-server/go.GetAlbum (3 handlers)[GIN-debug] PUT    /ikuokuo/start-openapitools/albums/:id --> github.com/ikuokuo/start-openapitools/gin-server/go.PutAlbum (3 handlers)[GIN-debug] GET    /ikuokuo/start-openapitools/albums --> github.com/ikuokuo/start-openapitools/gin-server/go.GetAlbums (3 handlers)[GIN-debug] POST   /ikuokuo/start-openapitools/albums --> github.com/ikuokuo/start-openapitools/gin-server/go.PostAlbums (3 handlers)[GIN-debug] Listening and serving HTTP on :8080❯ curl http://localhost:8080/ikuokuo/start-openapitools/Hello World!

生成 Client SDK 代码

生成 Python SDK 代码:

docker run --rm -it \-v "${PWD}:/local" \--entrypoint /bin/bash \openapitools/openapi-generator-cliln -s /usr/local/bin/docker-entrypoint.sh /usr/local/bin/openapi-generator# Config Options for python#  https://openapi-generator.tech/docs/generators/pythonopenapi-generator config-help -g pythonopenapi-generator generate \-g python \-i /local/spec/swagger.yaml \-o /local/out/py-sdk \--additional-properties=packageName=startapi \--additional-properties=library=urllib3

生成内容:

❯ tree out/py-sdk -aF --dirsfirstout/py-sdk├── .openapi-generator/├── docs/├── startapi/│   ├── api/│   │   ├── __init__.py│   │   ├── album_api.py│   │   └── albums_api.py│   ├── apis/│   │   └── __init__.py│   ├── model/│   │   ├── __init__.py│   │   └── album.py│   ├── models/│   │   └── __init__.py│   ├── __init__.py│   ├── api_client.py│   ├── configuration.py│   ├── exceptions.py│   ├── model_utils.py│   └── rest.py├── test/├── .gitignore├── .gitlab-ci.yml├── .openapi-generator-ignore├── .travis.yml├── README.md├── git_push.sh├── requirements.txt├── setup.cfg├── setup.py├── test-requirements.txt└── tox.ini

测试 SDK 应用,调用此前实现的 GetAlbum 接口:

❯ cd out/py-sdk/❯ python - <<EOFfrom startapi import ApiClient, Configuration, apisconfig = Configuration(host="http://localhost:8080/ikuokuo/start-openapitools")with ApiClient(configuration=config) as client:  api = apis.AlbumApi(client)  album = api.get_album("xxxxx")  print(album)EOF{'artist': 'GoCoding', 'created_at': datetime.datetime(2021, 11, 5, 18, 30, 0, 545305, tzinfo=tzoffset(None, 28800)), 'id': '3fa85f64-5717-4562-b3fc-2c963f66afa6', 'price': 0.99, 'title': 'Start OpenAPITools', 'updated_at': datetime.datetime(2021, 11, 5, 18, 30, 0, 545305, tzinfo=tzoffset(None, 28800))}

最初

实际下来,感觉不错。很多场合,生成 SDK 就够用了。另外,生成自动化测试代码,也值得一试。

GoCoding 集体实际的教训分享,可关注公众号!