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常用指令

  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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章