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-cli
- ln -s /usr/local/bin/docker-entrypoint.sh /usr/local/bin/openapi-generator
- openapi-generator help
- openapi-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.0
- info:
- title: Start OpenAPITools
- description: Let's practice designing our API.
- version: 0.1.0
- license:
- name: MIT
- url: https://spdx.org/licenses/MIT.html
- servers:
- - 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-cli
- ln -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-server
- openapi-generator config-help -g go-gin-server
- openapi-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 --dirsfirst
- out/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 id
- func 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-server
- go 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-cli
- ln -s /usr/local/bin/docker-entrypoint.sh /usr/local/bin/openapi-generator
- # Config Options for python
- # https://openapi-generator.tech/docs/generators/python
- openapi-generator config-help -g python
- openapi-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 --dirsfirst
- out/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.YAML
├── .openapi-generator-ignore
├── .travis.YAML
├── README.md
├── git_push.sh
├── requirements.txt
├── setup.cfg
├── setup.py
├── test-requirements.txt
└── tox.INI
测试 SDK 使用, 调用此前实现的 GetAlbum 接口:
- cd out/py-sdk/
- python - <<EOF
- from startapi import ApiClient, Configuration, apis
- config = 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 个人实践的经验分享, 可关注公众号!
来源: https://segmentfault.com/a/1190000040918517