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. 数据库删除discuz 部分数据操作

    如何快速清理discuz 3.2 中等待审核的回复数:pre_forum_post_moderate,点击清空 清空回收站的主题帖:DELETE FROM `pre_forum_thread` WHE ...

  2. ecshop商品批量上传之EC助理1.28支持ECshop2.7.3方法

    目前官方随着ECShop V2.73的发布也发布了相对应的EC助理1.30版.默认EC助理1.28也支持到ECShop V2.72,要想让EC助理1.28也支持到ECShop V2.73,那要了解EC ...

  3. Roslyn(CSharpScript).Net脚本编译引擎使用过程内存增涨与稳定的方式

    目       录 1.      引用程序集... 1 2.      内存增涨的情况... 2 3.      内存稳定的情况... 4 1.   引用程序集 Roslyn 是微软公司开源的 .N ...

  4. Docker系列(7)- 常用命令(3) | 容器命令

    容器命令 说明: 有了镜像才可以创建容器:下载一个centos镜像进行练习,相当于在Linux里面再见一个Linux虚拟机 [root@localhost ~]# docker pull centos ...

  5. Centos 7 设置 SFTP

    近期要给服务器设置一个SFTP用户,可以上传删除修改的SFTP,但是禁止该用户SSH登录.这里记录下来 先升级 来源: https://blog.csdn.net/fenglailea/article ...

  6. linux 下 svn配置;以及多仓库配置

    http://www.linuxidc.com/Linux/2016-01/127679.htm https://blog.csdn.net/mrwu9902/article/details/7869 ...

  7. opencv官宣

    opencv官方文档地址 https://docs.opencv.org/master/ 安装opencv(cv2)官方地址 https://pypi.org/project/opencv-pytho ...

  8. [转载]Nginx负载均衡配置实例详解

    负载均衡是我们大流量网站要做的一个东西,下面我来给大家介绍在Nginx服务器上进行负载均衡配置方法,希望对有需要的同学有所帮助哦. 负载均衡 先来简单了解一下什么是负载均衡,单从字面上的意思来理解就可 ...

  9. python爬虫与mysql,mongobd(1)(2)第一个视频python_pymysql 安装与使用类型,import解决 问题之模块引ru 就是解决你的问题

    import pymysql.cursors ''' 1.创建连接 2.创建游标 3.执行sql 5.接受结果 ''' # 1.连接 connection =pymysql.Connect( # 域名 ...

  10. RabbitMQ 3.9.7 镜像模式集群的搭建

    1. 概述 老话说的好:做人脚踏实地,一步一个脚印,便定能战胜一切困难,最终取得成功!!! 言归正传,之前我们聊了 RabbitMQ 单点服务的安装,今天我们来聊聊 RabbitMQ 3.9.7 镜像 ...