OpenAPITools can automatically generate server-side Stub code, client SDK code, and documentation based on REST API description files. OpenAPI Generator vs Swagger Codegen OpenAPI Generator vs Swagger Codegen

This article will design and write API files from scratch, and generate Go Gin server code, with Python SDK code. More languages or frameworks operate the same way.

Quick start

Get familiar with the tool first, directly use the official Docker image to generate Petstore sample Go SDK code:

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
Copy the code

Generate code in the current directory./out/go.

Open Swagger Editor File > Import URL to view 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
Copy the code

Hands-on practice

Design a RESTful API

Open the Swagger Editor design 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

The complete API description file is shown in spec/api.yaml and consists of three parts:

1 Header: API information

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
Copy the code

2 Middle: Paths and their operations (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
Copy the code

Bottom: reusable components, referenced by $ref in documentation

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
Copy the code

For details, see the OpenAPI Specification.

Online code generation

You can quickly generate code using an on-line service:

  • latest stable version: api.openapi-generator.tech

The following is a do-it-yourself process.

Generate Server Stub code

Generate the Go Gin Stub code:

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
Copy the code

Generated content:

❯ tree out/gin - server - aF - dirsfirst out/gin - server ├ ─ ─ the openapi - generator / ├ ─ ─ the API / │ └ ─ ─ openapi. Yaml ├ ─ ─ the go / │ ├ ─ ─ README. Md │ ├ ─ ─ api_album. Go │ ├ ─ ─ api_albums. Go │ ├ ─ ─ model_album. Go │ └ ─ ─ routers. Go ├ ─ ─ the openapi - generator - ignore ├ ─ ─ Dockerfile └ ─ ─ main. GoCopy the code

Simple implementation of GetAlbum interface at 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(),
	})
}
Copy the code

Running the service:

cd out/gin-server/
Initialize the module
go mod init github.com/ikuokuo/start-openapitools/gin-server
go mod tidy

# Change the import path in 'main.go'
# sw "github.com/ikuokuo/start-openapitools/gin-server/go"
# replace the cost path
go mod edit -replace github.com/ikuokuo/start-openapitools/gin-server/go=./go
Copy the code

Running results:

❯ 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] Runningin "debug" mode. Switch to "release" mode in production.
 - using env:   exportGIN_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 Handlers (3) [GIN - debug] Listening and serving HTTP on: 8080 ❯ curl http://localhost:8080/ikuokuo/start-openapitools/ Hello World!Copy the code

Generate Client SDK code

Generate Python SDK code:

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
Copy the code

Generated content:

❯ Flag Out/py-sdK-af -- Flag Out/py-SDK-af -- Flag Out/py-SDK-AF -- Flag Out/py-SDK-AF -- Flag Out/Py-SDK-AF Set py │ │ ├ ─ ─ album_api. Py │ │ └ ─ ─ albums_api. Py │ ├ ─ ─ apis / │ │ └ ─ ─ just set py │ ├ ─ ─ model / │ │ ├ ─ ─ just set py │ │ └ ─ ─ album. Py │ ├ ─ ─ models / │ │ └ ─ ─ just set py │ ├ ─ ─ just set py │ ├ ─ ─ api_client. Py │ ├ ─ ─ the configuration. The py │ ├ ─ ─ │ ├─ model_exercises. Py │ ├─ ├─ resttest/ ├─.Gitlab-ci.yML ├─.OpenApI-Generator-Ignore ├─.Travis ├─ ├─ customs.txt ├─ customs.txt ├─ customs.txt ├─ customs.txt ├─ customs.txt ├─ customs.txt ├─ customs.txt ├─ customs.txt ├─ customs.txt ├─ customs.txtCopy the code

To test the SDK use, call the previously implemented GetAlbum interface:

cdOut /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))}
Copy the code

The last

After practice, it feels good. In many cases, generating an SDK will suffice. Generating automated test code is also worth a try.

GoCoding personal practice experience sharing, please pay attention to the public account!