实用的Swagger Codegen


Swagger Codegen是什么?

这是Swagger Codegen项目,允许在给定OpenAPI规范的情况下自动生成API客户端库(SDK生成),服务器存根和文档。当前支持以下语言/框架:

SwaggerCodegen是根据OpenAPI规范转换文件并自动生成API客户端,存根服务器和文档的产品。
这次,我想写一下如何使用Swagger Codegen,如何扩展它以及实际使用中的问题。

昂首阔步的codegen

信息量非常小

关于这个。

用于日本材料

如此简单,自定义Swagger Codegen

只有大约


那么官方文件是什么?说到

https://github.com/swagger-api/swagger-codegen

只有大约20到30行,很难使用。
因此,如果您真的想使用它,则必须阅读Swagger Codegen的源代码。不出所料,这很痛苦。
因此,在本文档中,

目的是收集使用Swagger Codegen生成代码所需的文档链接,并使用示例和注释使代码生成尽可能容易。

环境介绍

swagger-codegen

的介绍

1
wget "http://central.maven.org/maven2/io/swagger/swagger-codegen-cli/2.4.6/swagger-codegen-cli-2.4.6.jar -O swagger-codegen-cli.jar"

这次,我想用Groovy做到这一点,就像我的前任所走的道路一样。
Groovy安装

1
$ apt-get install groovy

基本用法

有三种主要的使用Swagger Codegen的方法。

  • 使用SwaggerCodegen的内置代码生成功能
  • SwaggerCodegen扩展了带有模板的内置代码生成功能
  • 扩展Swagger Codegen的代码生成功能
  • 这次,我将解释在Swagger编辑器中使用示例yml。

    SwaggerCodegen使用内置代码生成功能

    这是

    1中的"使用Swagger Codegen的内置代码生成功能"的示例。

    1
    2
    3
    4
    $ java -jar swagger-codegen-cli.jar generate \
           -i swagger.yml \
           -l python \
           -o python_test

    -i中指定swagger yml文件,并在-l中指定要使用的语言。用-o指定输出目录。可以通过将langs设置为选项来确认可以使用-l指定的语言。

    1
    2
    3
    $ java -jar swagger-codegen-cli.jar langs
    > Available languages: [ada, ada-server, akka-scala, android, apache2, apex, aspnetcore, bash, csharp, clojure, cwiki, cpprest, csharp-dotnet2, dart, dart-jaguar, elixir, elm, eiffel, erlang-client, erlang-server, finch, flash, python-flask, go, go-server, groovy, haskell-http-client, haskell, jmeter, jaxrs-cxf-client, jaxrs-cxf, java, inflector, jaxrs-cxf-cdi, jaxrs-spec, jaxrs, msf4j, java-pkmst, java-play-framework, jaxrs-resteasy-eap, jaxrs-resteasy, javascript, javascript-closure-angular, java-vertx, kotlin, lua, lumen, nancyfx, nodejs-server, objc, perl, php, powershell, pistache-server, python, qt5cpp, r, rails5, restbed, ruby, rust, rust-server, scala, scala-gatling, scala-lagom-server, scalatra, scalaz, php-silex, sinatra, slim, spring, dynamic-html,
    html2, html, swagger, swagger-yaml, swift4, swift3, swift, php-symfony, tizen, typescript-aurelia, typescript-angular, typescript-inversify, typescript-angularjs, typescript-fetch, typescript-jquery, typescript-node, undertow, ze-ph, kotlin-server]

    SwaggerCodegen使用模板

    扩展了内置代码生成功能

    接下来是2。"使用模板扩展了Swagger Codegen内置的代码生成功能"。
    Swagger Codegen的代码生成功能由两个功能组成。一种是"代码生成器"和"模板功能"。 "模板功能"对于轻松扩展很有用。
    让我们以前面的Python示例输出为例。内置代码生成功能的模板可以在以下目录中找到。我将在此下载python。

    https://github.com/swagger-api/swagger-codegen/tree/prepare-release-2.4.6/modules/swagger-codegen/src/main/resources

    在这里,克隆swagger-codegen存储库并复制模板。

    1
    2
    $ git clone https://github.com/swagger-api/swagger-codegen.git
    $ cp -r swagger-codegen/modules/swagger-codegen/src/main/resources/python/ python_extend_template

    Swagger Codegen模板以称为胡须的模板语言编写。在这里,您可以轻松地重写名为requirements.mustache的模板。

    需求。胡子

    1
    2
    3
    4
    5
    6
    7
    certifi >= 14.05.14
    six >= 1.10
    python_dateutil >= 2.5.3
    setuptools >= 21.0.0
    urllib3 >= 1.15.1
    # テストで以下の行を追加
    tqdm

    如果您这样自己扩展模板,则可以使用以下命令将其输出。

    1
    2
    3
    4
    5
    $ java -jar swagger-codegen-cli.jar generate \
           -i swagger.yml \
           -l python \
           -t python_extend_template/ \
           -o python_extend_template_test

    值得注意的是-t选项,该选项在此参数中指定您自己的模板的文件夹。

    1
    2
    3
    4
    5
    6
    7
    8
    $ cat python_extend_template_test/requirements.txt  
    certifi >= 14.05.14
    six >= 1.10
    python_dateutil >= 2.5.3
    setuptools >= 21.0.0
    urllib3 >= 1.15.1
    # テストで以下の行を追加
    tqdm

    您可以确认以这种方式输出的文件已被更改。

    扩展了Swagger Codegen的代码生成功能

    此内容几乎是那么容易!Swagger Codegen定制
    将会是一样的。在本部分中,您将自己创建生成器。这次,该语言是TypeScript中的示例。

    样本生成器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    @Grab('io.swagger:swagger-codegen-cli:2.1.4')
    import io.swagger.codegen.*;
    import io.swagger.codegen.languages.*;

    class SampleTypeScriptClientGen extends AbstractTypeScriptClientCodegen {

      String name = "sample-typescript"
      String help = "Sample Codegen"

      public SampleTypeScriptClientGen() {
        super()
      }

      @Override
      public void processOpts() {
        super.processOpts();
        apiTemplateFiles.put("sample.mustache",".ts");
      }
    }

    SwaggerCodegen.main(args)

    作为最小示例,您需要实现namehelp的声明,构造函数和processOpts。
    接下来,创建一个模板。

    样品/样品。胡子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    export class {{classname}}Sample {
    {{#operations}}{{#operation}}
      public {{operationId}}(
        {{#allParams}}{{paramName}}:{{{dataType}}}{{#hasMore}},{{/hasMore}} {{/allParams}}
      ):
      {{^returnType}}void{{/returnType}}{{#returnType}} {{{returnType}}} {{/returnType}}
      { }
    {{/operation}}{{/operations}}
    }

    使用以下命令执行实际输出。

    1
    2
    3
    4
    5
    $ groovy sample-generator.groovy generate \
            -i swagger.yml \
            -l SampleTypeScriptClientGen \
            -t sample/ \
            -o sample_test

    这里有两点需要注意。这是-l选项传递的输出语言。这将是您先前在Groovy文件中声明的类名。另一个是-t,它指定包含您自己的模板的文件夹。
    实际输出结果如下。

    sample_test / PetApi.ts

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    export class PetApiSample {

      public updatePet(
        body:Pet
      ):
      void
      { }

      public addPet(
        body:Pet
      ):
      void
      { }
    (略)

    我认为您无法通过此示例判断自己在做什么。因此,以下各节中SwaggerCodeGen可以使用哪些语言?模板中可以使用哪些变量?该变量是什么意思?我想介绍这样的事情。

    自制发电机生产

    选择一种编程语言

    尽管Swagger先前与langs选项一起显示,但它支持一种相当大的编程语言的输出。

    https://github.com/swagger-api/swagger-codegen/tree/prepare-release-2.4.6/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages

    在著名的地方有Java,Php,TypeScript,Go等,但是在变体中也有Ada。
    通过继承此处的抽象类很容易创建。例如,在TypeScript中,您可以通过继承AbstractTypeScriptClientCodegen创建自己的生成器。以这种方式创建的生成器是同一文件夹中的TypeScriptAngularClientCodegen等。

    模板变量

    如先前示例中所述,Swagger主要使用模板函数来生成代码。在那里可以使用哪些变量?有两个文件会有所帮助。

    OpenAPI规范

    https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md

    这是Swagger遵循的规范的一部分。可以使用此处声明的大多数值。编写swagger.yml时,该文档也很有用,但很难阅读。

    Swagger API小胡子模板变量

    https://github.com/swagger-api/swagger-codegen/wiki/Mustache-Template-Variables

    您可以使用

    访问Swagger Codegen生成的类名,例如classname。另一个有用的示例是{hasMore},它也在上面使用过。

    1
     {{#allParams}}{{paramName}}:{{{dataType}}}{{#hasMore}},{{/hasMore}} {{/allParams}}

    定义

    函数的参数时,可能需要在参数之间添加","。那时,{{#hasMore}}用于确定它是否是最后一个对象,以及是否添加","。

    3个模板

    Swagger Codegen中有三个重要的代码生成模板。
    我将解释每个目的和用法。

    supportFiles

    实际规范是groovy文件中的

    1
    supportingFiles.put("sample.mustache",".ts")

    用作

    。这是使用模板的最简单方法,并且每次代码生成仅调用一次。
    实际使用的示例是typescript-node。

    实施:
    https://github.com/swagger-api/swagger-codegen/blob/prepare-release-2.4.6/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java <铅>

    模板:
    https://github.com/swagger-api/swagger-codegen/tree/prepare-release-2.4.6/modules/swagger-codegen/src/main/resources/typescript-node

    基本用法通常用于"非源代码"部分。在上面的示例中,它用于生成gitignore和package.json。 typescript-node是一个罕见的示例,并且源代码也仅由supportingFiles生成。因此,很容易阅读源代码作为起点。另一方面,胡子模板是残酷的,因为它被组合成一个代码。

    apiTemplateFiles

    用法如下。

    1
    apiTemplateFiles.put("api.mustache",".ts")

    主要用于使控制器成为api的一部分。
    但是,仅此一项,就会生成哪个源代码和哪个入口点?将生成多少个源代码?我想你一点都不知道。
    因此,我将参考样本swagger.yml的一部分进行解释。

    swagger.yml

    1
    2
    3
    4
    5
    6
    7
    8
    paths:
      /pet:
        post:
          tags:
          - "pet"
          summary: "Add a new pet to the store"
          description: ""
          operationId: "addPet"

    当您用

    快捷键指定入口点时,将使用属性path并声明url。此时,添加了属性tags。为每个tags属性生成源代码。
    在样本yml中,

    • 宠物
    • 用户
    • 商店

    有三个标签。生成的文件名将采用タグ名+第一引数のCamelCaseの.mustache抜き+apiTemplate.putの第2引数格式。因此,

    • 宠物小sprite
    • UserApi.ts
    • 仓库

    它将采用

    的形式。
    对于此处的正式实现,typescript-angular将很有帮助。

    实施:
    https://github.com/swagger-api/swagger-codegen/blob/prepare-release-2.4.6/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptAngularClientCodegen.java <铅>

    模板:
    https://github.com/swagger-api/swagger-codegen/tree/prepare-release-2.4.6/modules/swagger-codegen/src/main/resources/typescript-angular

    apiTemplateFiles.put文件:
    https://github.com/swagger-api/swagger-codegen/blob/prepare-release-2.4.6/modules/swagger-codegen/src/main/resources/typescript-angular/api.service.mustache

    很抱歉向您介绍,但是这段代码很难。这就是为什么我要这样做。请让您仿佛在营造一种氛围。

    modelTemplateFiles

    基本上,用法与apiTemplateFiles相同。

    1
    modelTemplateFiles.put("model.mustache",".ts")

    但是,处理目标不同,并且definitions是目标。
    如果您是参考sample.yml编写的,则

    sample.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    definitions:
      Order:
    # (略)
      Category:
    # (略)
      Tag:
    # (略)
      Pet:
    # (略)
      ApiResponse:
    # (略)

    的描述。可以在yml的底部提供子句definitions来定义唯一类型。这是模型的目标。在此示例中,

    • 订购
    • 类别
    • 标签
    • 宠物
    • Api响应

    为单位生成文件。
    这也与apiTemplate相同,并且typescript-angular会有所帮助。

    实施:
    https://github.com/swagger-api/swagger-codegen/blob/prepare-release-2.4.6/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptAngularClientCodegen.java <铅>

    模板:
    https://github.com/swagger-api/swagger-codegen/tree/prepare-release-2.4.6/modules/swagger-codegen/src/main/resources/typescript-angular

    但是,有很多地方可供阅读,所以我认为最好将其输出一次并仅选择所需的变量。而且我认为最好通过参考文档来添加缺失的内容。

    参考代码

    基本用法已结束,但是有时您需要遵循各种详细的行为。此处列出了可用作参考的源代码。

    DefaultGenerator.java
    https://github.com/swagger-api/swagger-codegen/blob/prepare-release-2.4.6/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java

    这是代码生成的主要部分。基本上,有必要查看此部分的行为。由于generateSupportingFiles,generateApis和generateModels是上述三个模板的处理部分,因此您可以通过详细阅读此区域来了解操作。

    CodegenConfig.java
    https://github.com/swagger-api/swagger-codegen/blob/prepare-release-2.4.6/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConfig.java

    这是Codegen的界面。 Codegen的目的是实现此接口。因此,没有逻辑。

    DefaultCodegen.java
    https://github.com/swagger-api/swagger-codegen/blob/prepare-release-2.4.6/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java

    DefaultCodegen是基本的代码生成逻辑。
    例如,如果您查看AbstractTypeScriptClientCodegen的定义,则

    https://github.com/swagger-api/swagger-codegen/blob/prepare-release-2.4.6/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractTypeScriptClientCodegen .java

    AbstractTypeScriptClientCodegen.java

    1
    public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig

    它是

    ,实现CodegenConfig,并继承DefaultCodegen。这样,似乎理论是在使用基本DefaultCodegen函数的同时实现CodegenConfig。但是,DefaultCodegen的代码相当糟糕,一个类中大约有3,900行,因此很难阅读。

    如何正确使用默认生成器和默认代码生成器?

    我将说明这一点,因为它变得越来越难以理解。

    image.png

    全部来自答案。默认生成器是Swagger Codegen代码生成过程的主体。定义了代码生成的整个流程,例如"首先,从apiTemplate的模板信息执行代码生成,然后modelTemplate为???"。 DefaultCodegen所做的只是设置代码生成。 DefaultGenerator中的api文件名是什么?调用(apiFilename)和CodeConfig。最初,在CodeConfig中实现的函数返回该值。由于DefaultCodegen在此处继承,因此将返回DefaultCodegen的apiFilename。顾名思义,DefaultCodegen是一个返回CodeConfig的Default值的类。

    印象数

    我在需要时阅读了Swagger Codegen,但这非常困难。我还没掌握全部内容。
    代码生成程序本身是一个困难的类别,因此非常严格。毕竟,有很多地方我动不动就无法理解。
    我想这样工作!即使您有这样的愿景,但由于Swagger Codegen的规范,这可能还是不可能的。但是,为了知道Swagger Codegen规范不可能做到的事情,我们必须知道Swagger Codegen规范。我陷入了僵局。
    另外,如果您不熟悉API代码结构,则还有一些困难的方面。例如,考虑使用Java Spring Boot构建API,必须在髭模板中一个接一个地编写导入语句。但是,代码完成可能不适用于此类情况,因此可能很烦人。因此,有必要以元方式识别代码,感觉就像是在用另一个大脑。
    在此处可能很难使用SwaggerCodegen,但是我希望本文对希望使用SwaggerCodegen的任何人有所帮助。
    那?它不是OpenAPI Generator吗???而且,Swagger是二进制2系统吗?有很多事情要做,但是???