1. 程式人生 > >API介面線上管理(Swagger和SosoApi)

API介面線上管理(Swagger和SosoApi)

1.Swagger
1.1. Swagger介紹
1.1.1. 簡介
Swagger是全球最大的API開發框架,這個框架以“開放API宣告(OpenAPI Specification,OSA)”為基礎,支援整個API生命週期的開發。它可以和SpringMVC整合,並且通過結合Swagger-ui元件,將controller層的方法進行視覺化的展示,像方法註釋,方法引數,方法返回值等都提供了相應的使用者介面。使用者可以在該介面對每個介面進行測試。
OSA,本身是一個規範,它是一個描述一整套API介面的json檔案,包括介面的請求方式,引數,header等等資訊。

1.1.2. 為什麼使用Swagger?
在工作中,如果開發人員遇到寫介面文件的工作,一般都是word文件,帶來書寫麻煩,維護麻煩的問題,比如改了原始碼忘了更新文件,解釋不明確帶來歧義,無法線上嘗試等等。而Swagger封裝了線上自動生成介面文件及進行功能測試的功能,正好可以解決這種問題。

1.1.3. 優缺點
優點:
 線上生成API文件並測試,易維護;
 可以和多種不同框架整合(除了SpringMVC,還有struts2,jersey2,cxf等等),應用範圍廣;
 測試的時候不需要再使用瀏覽器輸入URL的方式來訪問Controller,使用簡單方便,學習成本低。

缺點:
 沒有匯出的功能,文件只能在線看及線上測試,不能匯出到本地(這也是後面講SosoApi的原因)。
1.1.4. 用法比較
Swagger的使用有很多方式,這裡選取3種比較常用的使用方式來進行比較:
這裡寫圖片描述

Springfox是從元件swagger-springmvc發展而來,是一個新的專案,部署的時候,使用的是其中一個元件springfox-swagger2,該元件幫助我們生成描述API的json檔案。
上面用法各有優缺點,可按實際情況來選。大體上來說,Swagger4j和Springfox+Swagger2都在jar包中整合了Swagger UI元件,配置相對簡單。Springfox+Swagger2是Swagger的升級版本。
1.2. 本地部署
鑑於筆者所用框架為ssm,筆者在這裡只介紹Swagger整合SpringMVC進行本地部署。
1.2.1. Swagger部署
新建一個web maven 專案SwaggerProject,搭建好Spring+SpringMVC+MyBatis框架;
1.2.1.1. 新增依賴
在SwaggerProject中新增如下依賴:

<dependency>
    <groupId>com.mangofactory</groupId>
    <artifactId>swagger-springmvc</artifactId>
    <version>0.9.5</version>
</dependency>

1.2.1.2. 新增配置類
新增一個Swagger配置類,並在spring-mvc.xml檔案配置掃描這個類。

@Configuration
@EnableSwagger // 啟用Swagger
public class
MySwaggerConfig {
private SpringSwaggerConfig springSwaggerConfig; @Autowired public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig) { this.springSwaggerConfig = springSwaggerConfig; } @Bean public SwaggerSpringMvcPlugin customImplementation() { return new SwaggerSpringMvcPlugin(this.springSwaggerConfig).apiInfo(apiInfo()); } private ApiInfo apiInfo() { ApiInfo apiInfo = new ApiInfo( "My Apps API Title", "My Apps API Description", "My Apps API terms of service", "My Apps API Contact Email", "My Apps API Licence Type", "My Apps API License URL" ); return apiInfo; } }

1.2.1.3. 配置web.xml
在web.xml中進行如下配置,以啟動Servlet預設載入機制,確保SwaggerUI這些檔案不會被攔截。

<servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.jpg</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.png</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.gif</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.ico</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.js</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.css</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.xls</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.doc</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.json</url-pattern>
    </servlet-mapping>
    <!-- 字型相關  開始 -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.eot</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.svg</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.ttf</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.woff</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.woff2</url-pattern>
    </servlet-mapping>

1.2.1.4. 加入Swagger UI元件。
在github上下載Swagger UI元件,地址為:https://github.com/swagger-api/swagger-ui。解壓後將dist目錄下所有檔案拷貝到專案的webapp目錄下,並且修改index.html檔案中url為自己的“專案路徑/api-docs”。
1.2.1.5. 修改controller
先了解Swagger的幾個常用註解:
 @Api:表示這個類是Swagger的資源;
 @ApiOperation:用在方法上,說明方法的作用。
 @ApiParam:用來修飾引數,表示對引數新增元資料
 @ApiModel:用於類,對類進行說明
 @ApiIgnore:用於類,方法,表示這個類或方法被忽略;
 @ApilmplicitParam:用於方法,表示單獨的請求引數;
修改後的controller及方法一般形式如下:

@Api(value = "/user", description = "關於使用者的一些操做")
@Controller
public class UserController {
    @ResponseBody
    @RequestMapping(value = "getUserById", method = RequestMethod.GET)
    @ApiOperation(value = "通過ID查詢USER資訊", httpMethod = "GET", notes = "暫無")
    public String getUserById(
            @ApiParam(required = true, name = "id", value = "ID") 
            @RequestParam(value = "id") int id,HttpServletRequest request) {
        User user = new User();
        user.setId(id);
        user.setName("測試人員");
        user.setAge(25);
        JSONObject object = JSONObject.fromObject(user);
        return object.toString();
    }
}

這些註解並不一定都要用到,實際上,由於Spring已經提供了一套完整的註解方式,這些Swagger的註解起的只是錦上添花的作用。在結合我們專案進行測試的過程中,為了使程式碼的改動最小,我並沒有使用這些註釋,而是保持原有程式碼不變,然後為原來的@RequestMapping註解新增請求方式,並根據請求引數型別給請求引數新增@RequestParam或@RequestBody註解。
1.2.1.6. 啟動並測試
將專案新增到tomcat,並啟動tomcat,正常會出現如下介面:
這裡寫圖片描述

點選列表上面的“Expand Operations”選項,可以彈出如下介面:
這裡寫圖片描述
在這裡,可以對每個介面進行測試。

1.2.2. Swagger4j部署
1.2.2.1. 新增依賴

<dependency>
    <groupId>com.cpjit</groupId>
    <artifactId>swagger4j</artifactId>
    <version>2.1.1</version>
</dependency>

1.2.2.2. 修改spring-mvc.xml
在spring-mvc.xml檔案中新增如下程式碼以載入jar包中的Swagger UI元件:

    <mvc:resources mapping="/**/*.css" location="/" />
    <mvc:resources mapping="/**/*.js" location="/" />
    <mvc:resources mapping="/**/*.png" location="/" />
    <mvc:resources mapping="/**/*.gif" location="/" />
    <mvc:resources mapping="/**/*.jpg" location="/" />
    <mvc:resources mapping="/**/*.ico" location="/" />
    <mvc:resources mapping="/**/*.woff" location="/" />
    <mvc:resources mapping="/**/*.woff2" location="/" />
    <mvc:resources mapping="/**/*.fft" location="/" />
    <mvc:resources mapping="/**/*.svg" location="/" />
    <mvc:resources mapping="/**/*.eot" location="/" />
    <mvc:resources mapping="/**/*.html" location="/" />
    <mvc:resources mapping="/**/*.mp3" location="/" />

1.2.2.3. 新增配置檔案
新建配置檔案swagger.properties(這個名稱是唯一的),注意第一項要掃描的包路徑要改成自己專案的需要掃描的路徑。

packageToScan=com.cpjit.swagger4j.demo
apiDescription=Swagger Demo
apiTitle=Swagger Demo
apiVersion=1.0.0
teamOfService=www.cpj.com
devMode=true
disabled=false

1.2.2.4. 修改controller
首先了解幾個重要的註解:
@APIs:該註解放在一個類上面,用來表明類中包含作為HTTP介面的方法,該註解的value用來設定介面的字首;
@API:該註解放在一個方法上面,用來表明方法是HTTP介面方法,註解的屬性說明如下:
 value:與@APIs的value屬性一起來指定介面的地址。
 parameters:用來指定介面的請求引數;
 summary:介面功能簡述;
 description:介面功能詳細說明;
 method:請求方式,預設是post。
@Param:用來說明請求引數。
Controller層的類和方法的形式大致如下:

@Controller
@RequestMapping("/demo")
@APIs("/demo")
public class DemoController {
    @API(value="login", summary="示例1", parameters={
            @Param(name="username", description="使用者名稱", dataType=DataType.STRING, defaultValue = "admin"),
            @Param(name="password", description="密碼", dataType=DataType.PASSWORD),
            @Param(name = "sex", description = "性別", dataType = DataType.ARRAY, items = "sex"),
            @Param(name = "age", description = "年齡", dataType = DataType.INTEGER, defaultValue = "18"),
            @Param(name="image" , description="圖片", dataType=DataType.FILE)
    })
    @RequestMapping(value="login", method=RequestMethod.POST)
    public void login(@RequestParam Map<String, Object> param, MultipartFile image, HttpServletResponse response) throws Exception {
        response.setContentType("application/json;charset=utf-8");
        JSONWriter writer = new JSONWriter(response.getWriter());
        writer.writeObject(param);
        writer.flush();
        writer.close();
    }

1.2.3. Springfox+Swagger2部署
1.2.3.1. 新增依賴

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.5.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.5.0</version>
        </dependency>

1.2.3.2. 修改spring-mvc.xml檔案

<mvc:resources location="classpath:/META-INF/resources/" mapping="swagger-ui.html" />
<mvc:resources location="classpath:/META-INF/resources/webjars/" mapping="/webjars/**" />

1.2.3.3. 新增配置檔案
新建SwaggerConfig.java檔案,新增如下程式碼:

@Configuration
@EnableWebMvc // 支援springmvc
@EnableSwagger2 // 啟用Swagger2
@Component
public class SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
            .apis(RequestHandlerSelectors.basePackage("com.chen.controller"))
            // 掃描所有有註解的api
            .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any()).build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("RESTful APIs").description("Spring+MVC集合Swagger2的API")
            .termsOfServiceUrl("http://localhost:8080").version("1.0.0").build();
    }
}

1.2.3.4. 修改controller
各個註解和Swagger部署中的意思是一樣的。Controller層的方法一般形式如下:

@Api(value = "UserInfoController", description = "UserInfoController", position = 1)
@Controller
@RequestMapping("/UserInfoController")
public class UserInfoController {

    @ResponseBody
    @ApiOperation(value = "查詢使用者", notes = "返回使用者實體物件", position = 1)
    @RequestMapping(value = "/query", method= RequestMethod.POST)
    public UserInfo query(@RequestParam(value="id")Long id){
        UserInfo userInfo = new UserInfo();
        userInfo.setId(id);
        userInfo.setName("張三");
        userInfo.setAddress("廣州");
        return userInfo;
    }
}

點選右上角“Expand Operations”,出現如下介面,這時候就可以測試了。
這裡寫圖片描述

它主要是通過EnableSwagger2註解,向srping context注入了一系列bean,並在系統啟動的時候自動掃描系統的Controller類,生成相應的api資訊並快取起來。此外,它還注入了一些被@Controller註解標識的Controller類,作為ui模組訪問api列表的入口。

1.2.4. 原理分析
SpringMVC+Swagger自動生成線上api文件,其實就是在系統載入的時候,Swagger配置類去掃描所有添加註解的介面,並且儲存起來生成完整的json檔案,然後使用Swagger-UI元件,將這個json檔案解析出來,用一種更友好的方式呈現出來。

2.SosoApi
2.1. 簡介
是一個專注於API介面文件管理及線上線下測試的API服務平臺。

2.2. 特點
 提供豐富的線上文件,包括線上編輯和線下部署及常見問題,減少上手學習成本。
 通過編輯表單的方式建立基於swagger ui的資料文件,從而可線上預覽和測試。
 解決了swagger editor學習成本高及程式碼整合不好維護的問題。
 為方便小團隊及公司內部使用,可匯出swagger資料文件線下部署。
 不會對已有專案產生任何程式碼入侵。

2.3. 使用
2.3.1. 線上使用
登入http://www.sosoapi.com官網使用,上面有詳細的指導手冊,大家一看就明白了。這裡主要補充一點:sosoapi去年還沒有新增“匯入”的功能,今年增加了,但只有在線的版本有匯入功能,開源版本沒有,所以筆者推薦使用線上版本以節省人力。有了匯入功能,那麼只要匯入介面的json檔案就可以自動生成介面文件了(剛好swagger可以生成json檔案),我們只要輸入必要的引數就可以進行測試了。

下載sosoapi-web 和 framework 專案,匯入eclipse。然後再用maven構建一下。注意,sosoapi-web 依賴 frameWork專案。
然後根據db目錄下的sosoapi.sql檔案,建立資料庫並執行sql指令碼,修改與資料庫相關的各個配置檔案。
本地執行該專案,埠號為8080,若一切正常,訪問http://localhost:8080/sosoapi-web會出現如下介面:
這裡寫圖片描述

之後的操作和線上使用的方式是一樣一樣的。

  1. 對比Swagger與SosoApi
    下面是Swagger與SosoApi的一些比較:
    這裡寫圖片描述

之所以把Swagger和SosoApi放在一起講,是因為筆者暫時沒有找到既可以自動生成API文件,又能匯出文件的方法。這兩種各有其作用,根據需求及專注的重點,選擇其中一種或兩者皆選。就筆者認為,若專案不要求提供線下的API文件或不要求對Api進行整體管理,應當選擇Swagger(或者啥都不選,寫測試用例也很好)。反之則同時使用Swagger和SosoApi,使用Swagger生成json檔案,然後將json檔案匯入sosoapi,就可以得到介面文件及可匯出多種格式的介面文件。