美文网首页
OpenAPITools 实践

OpenAPITools 实践

作者: GoCodingInMyWay | 来源:发表于2021-11-05 22:56 被阅读0次

    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:

    image

    查看 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 实践

          本文链接:https://www.haomeiwen.com/subject/obddzltx.html