swagger生成对应的客户端、服务端代码

根据yaml文件生成对应的客户端、服务端代码

前言

​ 对于早期的webservice接口,我们可以根据wsdl文件生成对应的客户端和服务端代码。那么同样的针对于Restful风格的接口,也有同样的根据可以生成对应的客户端和服务端代码。这里我主要讲解一种根据yaml描述文档生成客户端、服务端代码的方式是Swagger。

Swagger介绍

​ 相信很多人对于Swagger并不陌生,甚至也使用过Swagger,但是提到Swagger,大部分应该用到的更多是借助Swagger来生成对应的API文档,要不然也不至于我苦苦找不到相关资料。当然生成API文档的方法有很多,大家可以自行百度,在这里不是我要讲述的重点。今天在这里我重点要讲述的是----如何通过Swagger来生成客户端和服务端代码。
​ Swagger是一组开源项目,官网地址是(https://swagger.io/),并提供了一系列的组件,可以参见github地址(https://github.com/swagger-api/)

  • **swagger-core :**用于生成Swagger API规范的示例和服务器集成,可轻松访问REST API
  • **swagger-codegen :**通过Codegen 可以将描述文件生成对应的客户端、服务端代码及API文档
  • **swagger-ui :**一个无依赖的HTML、JS和CSS集合,可以为Swagger兼容API动态生成优雅文档
  • **swagger-editor :**swagger官方提供的编辑器,用于编写API设计文档

接下来我会着重介绍下swagger-codegen的使用

Swagger-codegen

​ swagger-codegen在github上官方没有直接发布的版本,所以我们需要将其源码从github上下载下来自行编译,编译过程也很简单,使用说明在首页的readme中详细描述,只不过是英文的,那我在这里就做个简单的转移吧。github地址:https://github.com/swagger-api/swagger-codegen

编译swagger-codegen
  1. 执行命令,从github上将源码down下来
    git clone https://github.com/swagger-api/swagger-codegen.git
  2. 切换到swagger-codegen目录下,执行maven打包命令,生成swagger-codengen-cli.jar
    mvn clean package
  3. 生成的swagger-codengen-cli.jar在./modules/swagger-codegen-cli/target下,如图所示:在这里插入图片描述
swagger-codengen-cli.jar常用指令

以下指令需要在swagger-codegen-cli.jar所在的目录执行

  1. 查看帮助文档
    java -jar swagger-codegen-cli.jar help
  2. 查看支持的语言
    java -jar swagger-codegen-cli.jar langs

​ 输出的结果如下,这是当前2.4.13版本支持的语言如下:

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, swift5, 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]
  1. 查看调用生成代码指令支持的参数java -jar swagger-codegen-cli.jar help generate,执行命令后可以看到有很多的参数以及配置项(输出结果就不在这里贴出来了),但我们常用的参数有这么几项,大部分的参数都可以单独配置到一个配置文件中,这个待会儿在下一个节点单独介绍。常用参数如下:
    • -i : 指定接口描述文件
    • -c : 指定配置项所在的配置文件
    • -D : 指定虚拟机参数。例如指定生成代码的groupId:-D --group-id com.monk.demo
    • -l : 指定生成代码的语言(生成客户端和服务端代码的区别就是通过语言的不同来区分的)
  • -o : 指定生成代码的路径
  1. 查看将要生成语言的代码支持的配置参数,这里以java语言为例。

    java -jar swagger-codegen-cli.jar config-help -l java,输出结果就不在这里贴出来了,大家可以执行下之后看下输出的内容。我这里也整理了下,最常用的参数有这些,如下:

    • apiPackage:生成的api包名
    • modelPackage:生成的api包名
    • sourceFolder:生成的源码文件夹。例如/src/main/java
    • java8:是否支持java8。默认false
    • groupId:生成的mavne项目的坐标groupId
    • artifactId:生成的mavne项目的坐标artifactId
    • artifactVersion:生成的mavne项目的坐标artifact版本号
    • artifactDescription:生成的mavne项目的artifact描述信息

    还有一些参数时配置开发者信息、联系方式等等无关痛痒的参数,我就不再这里列出了,如果有需要可以适当的配置进去,各取所需吧

通过swagger-code生成客户端、服务端代码

提示: 这一章节只介绍怎么生成代码,测试环境见一下章节

通过swagger-code生成客户端和服务端的代码,目前我所知道的有三种,分别如下:

  1. 通过swagger-codegen-cli.jar包生成
  2. 通过java代码来生成
  3. 通过maven-plugin的方式生成

接下来将分别介绍如何通过这三种方式生成代码:
在开始之前,我们得先在本地准备两个配置文件,用于指定生成客户端、服务端代码的配置:

  1. 接口的描述文件(这里我们直接拿官网提供的接口描述文件来示例,描述文件在**./modules/swagger-codegen/src/test/resources/2_0/petstore.yaml**)。这里我们将这个文件复制到D:\temp目录下去,并修改这个文件中的内容,修改的地方如图所示:在这里插入图片描述

  2. 生成代码的公共配置文件(也就是上面 -c参数需要指定的配置文件)

    • 服务端代码配置文件

      文件内容如下:(将其保存为swagger-server.json,保存在D:\tmep\swagger-server目录下)

      {
      	"invokerPackage": "com.monk.client",
      	"apiPackage": "com.monk.client.api",
      	"modelPackage": "com.monk.client.bean",
      	"sourceFolder": "src/main/java",
      	"java8": true,
      	"dateLibrary": "java8",
      	"groupId": "com.monk",
      	"artifactId": "swagger-client",
      	"artifactVersion": "1.0.0",
      	"artifactDescription": "This is a demo for generate java client by swagger-codegen."
      }
      
    • 客户端代码配置文件

      文件内容如下:(将其保存为swagger-client.json,保存在D:\tmep\swagger-client目录下)

      {
      	"invokerPackage": "com.monk.server",
      	"apiPackage": "com.monk.server.api",
      	"modelPackage": "com.monk.server.bean",
      	"configPackage": "com.monk.server.config",
      	"java8": true,
      	"groupId": "com.monk",
      	"artifactId": "swagger-server",
      	"artifactVersion": "1.0.0",
      	"artifactDescription": "This is a demo for generate java server by swagger-codegen."
      }
      

然后将刚刚我们编译的swagger-codegen-cli.jar复制到D:\temp目录下。最终的目录结构如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zU9hK8a6-1584199218594)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20200306203352004.png)]

通过swagger-codegen-cli.jar包生成

关于swagger-codegen-cli.jar包的使用方法以及参数介绍,在上一章节已经介绍过了,这里就直接开始生成了,又不懂和疑问的地方,请联系我。

生成服务端代码

指令如下:

java -jar swagger-codegen-cli.jar generate -i .\petstore.yaml -l spring -c .\swagger-server\swagger-server.json -o .\swagger-server

至此,服务端代码生成成功。

生成客户端代码

指令如下:

java -jar swagger-codegen-cli.jar generate -i .\petstore.yaml -l java -c .\swagger-client\swagger-client.json -o .\swagger-client

就这么简单,客户端代码到目前为止也生成成功了。

通过java代码来生成

参见编译swagger-codegen章节,我们重新编译下源码,需要将生成的swagger-codegen-cli.jar安装到我们maven的本地的仓库中,然后通过依赖的方式加入到项目中。修改编译的指令为mvn clean package install

  1. 我们新建一个maven项目swagger-codegen-demo,在pom文件中加入以下依赖

    <dependency>
        <groupId>io.swagger</groupId>
        <artifactId>swagger-codegen-cli</artifactId>
        <version>2.4.13-SNAPSHOT</version>
    </dependency>
    
  2. 新建测试类,添加main方法,编写以下代码

    package com.monk;
    
    import io.airlift.airline.Cli;
    import io.airlift.airline.Help;
    import io.swagger.codegen.cmd.*;
    
    /**
     * Hello world!
     *
     */
    public class App 
    {
        public static void main( String[] args )
        {
            Cli.CliBuilder<Runnable> builder =
                    Cli.<Runnable>builder("swagger-codegen-cli")
                            .withDescription(
                                    String.format(
                                            "Swagger code generator CLI (version %s). More info on swagger.io",
                                            "2.4.5"))
                            .withDefaultCommand(Langs.class)
                            .withCommands(Generate.class, Meta.class, Langs.class, Help.class,
                                    ConfigHelp.class, Validate.class, Version.class);
    
             // 生成客户端代码
            builder.build().parse(new String[]{
                    "generate",
                    "-i",
                    "D:\\temp\\petstore.yaml",
                    "-l",
                    "java",
                    "-o",
                    "D:\\temp\\java\\swagger-client",
                    "-c",
                    "D:\\temp\\swagger-client\\swagger-client.json"
            }).run();
    
            // 生成服务端代码
            builder.build().parse(new String[]{
                    "generate",
                    "-i",
                    "D:\\temp\\petstore.yaml",
                    "-l",
                    "spring",
                    "-o",
                    "D:\\temp\\java\\swagger-server",
                    "-c",
                    "D:\\temp\\swagger-server\\swagger-server.json"
            }).run();
        }
    }
    
  3. 这里不难发现,其实和我们调用的jar包的方式生成代码是一样的,只不过将命令换一种方式去执行而已。

通过maven-plugin的方式生成

  1. 接着上一章节来,我们将对应的资源文件添加项目的src/main/resources目录下;
    1. 接口描述文件 petstore.yaml
    2. 客户端配置文件 swagger-client.json
    3. 服务端配置文件 swagger-server.json
  2. 然后修改对应的pom文件
<!-- 添加属性 -->
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <swagger-server-output-dir>D:\temp\plugin\swagger-server</swagger-server-output-dir>
    <swagger-client-output-dir>D:\temp\plugin\swagger-client</swagger-client-output-dir>
    <swagger-codengen-input-yml>src/main/resources/petstore.yaml</swagger-codengen-input-yml>
    <swagger-client-config-json>src/main/resources/swagger-client.json</swagger-client-config-json>
    <swagger-server-config-json>src/main/resources/swagger-server.json</swagger-server-config-json>
</properties>

<build>
    <plugins>
        <plugin>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-codegen-maven-plugin</artifactId>
            <version>2.3.1</version>
            <configuration>
            <inputSpec>${swagger-codengen-input-yml}</inputSpec>
            <!--生成服务端代码-->
            <!--<language>spring</language>
            <output>${swagger-server-output-dir}</output>
            <configurationFile>${swagger-server-config-json}</configurationFile>-->
            <!--  生成客户端代码  -->
            <language>java</language>
            <output>${swagger-client-output-dir}</output>
            <configurationFile>${swagger-client-config-json}</configurationFile>
          </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
  1. 借助maven来生成对应的客户端喝服务端代码。

开发并测试我们的服务端以及服务端

下文中的开发和测试,均用PetApi.findPetsByStatus(List status)方法来演示

开发服务端代码

首先打开刚刚生成的服务端代码,打开PetApi.java类,找到对应的findPetsByStatus(List status)方法,服务端的逻辑代码就可以写在这里。

下面我就修改生成的代码,修改其返回值,如图所示:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nuc8M4e8-1584199218597)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20200306221751568.png)]

由于生成的服务端是一个spring-boot项目,我们可以直接找到Swagger2SpringBoot.java类,右键**Run ‘Swagger2SpringBoot’**等待启动成功即可。

PS:

  1. 关于springBoot的启动端口,项目的contextPath怎么配置及怎么看,这里就不再赘述了,请自行百度。
  2. 又由于是个springBoot项目,我们也可以用maven命令maven clean package将项目打成jar包,然后用cmd命令java -jar swager-server.jar来启动项目。

开发客户端代码

打开刚刚生成的swagger-client项目,有以下几个地方需要注意一下:

  1. 打开ApiClient.java类,检查下私有全局变量basePath是否设置的是服务端的地址http://localhost:8080,如果不是的话,就更正为自己的服务端地址。如图所示:(正常情况是不会生成错的,但是还是检查下,否则会抛出ApiException) [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YYeqNe3C-1584199218600)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20200307000025222.png)]

  2. 在生成客户端代码的同时,也会为我们生成一份测试用例,只不过这个测试用例是空的,并且是加了**@Ignore注解的,那么我们需要简单的修改一下。和服务端代码相呼应,我们这里继续拿PetApiTest**类来演示,如下所示:

    • 首先将类上的**@Ignore**注解去掉

    • 完善测试用例方法,如下所示:

      @Test
      public void findPetsByStatusTest() throws ApiException {
          List<String> status = new ArrayList<String >();
          // 如果你看懂了服务端的代码,就明白这里填写任意值是不影响我们的返回结果的,只要不为空就好
          status.add("available");
          List<Pet> response = api.findPetsByStatus(status);
          response.forEach(item->{
              System.out.println(item);
          });
      }
      
  3. 最终的输出结果如图所示:在这里插入图片描述

客户端的调用

我们可以将我们生成的客户端代码打包并添加到我们的本地maven仓库,这样别人就可以直接通过添加这个jar的依赖就可以完成对服务端的调用。

  1. 使用maven指令将swagger-client打包到本地maven仓库mvn clean install -Dmaven.test.skip=true

  2. 打开上面新建的测试项目swagger-codegen-demo,添加以下依赖:

     <dependency>
         <groupId>com.monk</groupId>
         <artifactId>swagger-client</artifactId>
         <version>1.0.0</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    
  3. 新建测试类TestClientApi,编写测试方法testApi(),如下所示:

    @Test
    public void testApi() throws ApiException {
        PetApi api = new PetApi();
        List<String> status = new ArrayList<String >();
        // 如果你看懂了服务端的代码,就明白这里填写任意值是不影响我们的返回结果的,只要不为空就好
        status.add("available");
        List<Pet> response = api.findPetsByStatus(status);
        response.forEach(item->{
            System.out.println(item);
        });
    }
    
  4. 输出结果如图所示:
    在这里插入图片描述

总结

​ 通过三种生成客户端、服务端代码方式的比较,生成代码的方式都是围绕着swagger-codegen-cli这个jar包转,除开maven-plugin的方式一时想不到合适的应用场景外,我觉得另外两个方式各自有各自的场景。比方说:我们在实际项目中根据接口描述文档开发的时候就可以用jar包生成的方式;而用java代码的方式生成的话,我觉得可以集成我们的管控平台上,就可以像sawgger官方的编辑器一样了,管控一键生成接口设计文档,然后再根据设计文档生成对应的客户端代码、服务端代码,将代码打包提供下载即可。

​ 通篇看完,估计你也在疑惑,为什么指定的language不同,理论上spring也是java呀,java生成的就是客户端,spring生成的就是服务端。开始我也很纳闷,甚至在看github的官方文档的时候,关于生成客户端代码,花了大篇幅来简述怎么生成客户端代码,可以参见To generate a sample client library,而怎么生成服务端代码就一句话,参见To build a server stub,然而这句话还是一句超链接,跳到了另外一个地方,如图所示:
在这里插入图片描述
他在这里列举了一些服务端代码怎么生成,大家也可以自行去浏览一下https://github.com/swagger-api/swagger-codegen/wiki/Server-stub-generator-HOWTO

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值