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 集体实际的教训分享,可关注公众号!