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

在线生成代码

可以用线上服务快速生成代码:

以下则是自己动手生成的过程。

生成 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.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 - <<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 个人实践的经验分享,可关注公众号!

OpenAPITools 实践的更多相关文章

  1. webp图片实践之路

    最近,我们在项目中实践了webp图片,并且抽离出了工具模块,整合到了项目的基础模板中.传闻IOS10也将要支持webp,那么使用webp带来的性能提升将更加明显.估计在不久的将来,webp会成为标配. ...

  2. Hangfire项目实践分享

    Hangfire项目实践分享 目录 Hangfire项目实践分享 目录 什么是Hangfire Hangfire基础 基于队列的任务处理(Fire-and-forget jobs) 延迟任务执行(De ...

  3. TDD在Unity3D游戏项目开发中的实践

    0x00 前言 关于TDD测试驱动开发的文章已经有很多了,但是在游戏开发尤其是使用Unity3D开发游戏时,却听不到特别多关于TDD的声音.那么本文就来简单聊一聊TDD如何在U3D项目中使用以及如何使 ...

  4. Logstash实践: 分布式系统的日志监控

    文/赵杰 2015.11.04 1. 前言 服务端日志你有多重视? 我们没有日志 有日志,但基本不去控制需要输出的内容 经常微调日志,只输出我们想看和有用的 经常监控日志,一方面帮助日志微调,一方面及 ...

  5. 【大型网站技术实践】初级篇:借助Nginx搭建反向代理服务器

    一.反向代理:Web服务器的“经纪人” 1.1 反向代理初印象 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从 ...

  6. Windows平台分布式架构实践 - 负载均衡

    概述 最近.NET的世界开始闹腾了,微软官方终于加入到了对.NET跨平台的支持,并且在不久的将来,我们在VS里面写的代码可能就可以通过Mono直接在Linux和Mac上运行.那么大家(开发者和企业)为 ...

  7. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

  8. Mysql事务探索及其在Django中的实践(一)

    前言 很早就有想开始写博客的想法,一方面是对自己近期所学知识的一些总结.沉淀,方便以后对过去的知识进行梳理.追溯,一方面也希望能通过博客来认识更多相同技术圈的朋友.所幸近期通过了博客园的申请,那么今天 ...

  9. netty5 HTTP协议栈浅析与实践

      一.说在前面的话 前段时间,工作上需要做一个针对视频质量的统计分析系统,各端(PC端.移动端和 WEB端)将视频质量数据放在一个 HTTP 请求中上报到服务器,服务器对数据进行解析.分拣后从不同的 ...

随机推荐

  1. kibana操作

    一些KIBANA的操作,记录下,免下次重复写 #创建索引名为kb_question的索引,并添加mapping,即各字段属性 PUT kb_question { "mappings" ...

  2. P4480-[BJWC2018]餐巾计划问题【三分,贪心】

    正题 题目链接:https://www.luogu.com.cn/problem/P4480 题目大意 \(n\)天,第\(i\)天需要\(a_i\)个餐巾. 每个餐巾价格为\(p\),使用完后有两种 ...

  3. 使用AC自动机解决文章匹配多个候选词问题

    解决的问题 KMP算法用于单个字符串匹配,AC自动机用于文章中匹配多个候选词. 流程 第一步,先将候选词先建立前缀树. 第二步,以宽度优先遍历的方式把前缀树的每个节点设置fail指针, 头节点的fai ...

  4. 未能加载文件或程序集“System.Net.Http

    前言 简单说先事情的起因吧,之前的程序写了有一段时间了,最近要添加新的功能.顺手就把NuGet包全部更新到最新版.随之问题就出现了. 开始以为是.NET Framework 库的原因,之前是4.6.1 ...

  5. Jetbrains CLion 安装与激活 详解

    1. 下载与安装 1.1 下载 这里提供了三个操作系统的官网下载地址 Mac Windows Linux 进入页面后向下拉点击蓝色按钮即可下载. 1.2 安装 这里将用 MacOS 来进行示例,Win ...

  6. try catch中的return与finally

    try catch中的return与finally 代码为 public class Test{ public int add(int a,int b){ try { return a+b; } ca ...

  7. gin 集成 consul

    "github.com/hashicorp/consul/api" package initialize import ( "fmt" "github ...

  8. Analysis Tools(分析工具)

    分析工具 1.叠加分析 # Process: 交集取反 arcpy.SymDiff_analysis("", "", 输出要素类, "ALL" ...

  9. SpringCloud升级之路2020.0.x版-27.OpenFeign的生命周期-创建代理

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 接下来,我们开始分析 OpenFeign 的生命周期,结合 OpenFeign 本身的源代 ...

  10. 接口自动化-Python3+request上传文件,发送multipart/form-data编码

    1.安装requests_toolbelt   pip install requests-toolbelt 2.发送文件中的数据 from requests_toolbelt import Multi ...