溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Spring Cloud微服務(wù)接口管理工具

發(fā)布時(shí)間:2020-06-10 15:36:57 來源:億速云 閱讀:866 作者:元一 欄目:編程語言

前言

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的開發(fā)便利性巧妙地簡化了分布式系統(tǒng)基礎(chǔ)設(shè)施的開發(fā),如服務(wù)發(fā)現(xiàn)注冊(cè)、配置中心、消息總線、負(fù)載均衡、斷路器、數(shù)據(jù)監(jiān)控等,都可以用Spring Boot的開發(fā)風(fēng)格做到一鍵啟動(dòng)和部署。Spring Cloud并沒有重復(fù)制造輪子,它只是將各家公司開發(fā)的比較成熟、經(jīng)得起實(shí)際考驗(yàn)的服務(wù)框架組合起來,通過Spring Boot風(fēng)格進(jìn)行再封裝屏蔽掉了復(fù)雜的配置和實(shí)現(xiàn)原理,最終給開發(fā)者留出了一套簡單易懂、易部署和易維護(hù)的分布式系統(tǒng)開發(fā)工具包。

根據(jù)各個(gè)微服務(wù)功能邊界定義的不同,有些微服務(wù)會(huì)提供與具體業(yè)務(wù)相關(guān)的接口,如支付接口、賬戶接口等;而有些微服務(wù)則會(huì)提供一些公共性質(zhì)的服務(wù)接口,如短信接口、統(tǒng)一認(rèn)證接口之類。而這些微服務(wù)往往又是由多個(gè)不同的團(tuán)隊(duì)在開發(fā)維護(hù),傳統(tǒng)方式下服務(wù)接口的定義往往需要服務(wù)提供方提供良好的、可閱讀性比較高的接口文檔才可以比較方便地對(duì)接和測試,而事實(shí)上,隨著時(shí)間的推移、人員的迭代更新,很多情況下這些早期的接口文檔往往很快就會(huì)因?yàn)闊o人維護(hù)而過時(shí),即便不過時(shí),微服務(wù)模式下這樣的方式也會(huì)因?yàn)榉?wù)接口文檔太多而讓開發(fā)人員顯得抓狂!

那么有沒有一種更便捷地方式,可以讓開發(fā)接口的同時(shí),自動(dòng)就能生成與服務(wù)接口高度一致的文檔來呢?答案是有的,接下來就和大家一起聊聊到底有什么樣方式可以讓微服務(wù)的接口管理變得更加容易些!

接口管理方式介紹

事實(shí)上,市面上已經(jīng)有多種開源項(xiàng)目提供了這樣的支持!如:Swagger、ApiDoc、RAP、DOCLever、CrapApi等,這些項(xiàng)目都提供了對(duì)于Api在線文檔的管理功能,那么在Spring Cloud體系中哪一種方式更加適合呢?下面,我們一起來對(duì)比下這些項(xiàng)目的優(yōu)缺點(diǎn)。

Swagger

Swagger是一款基于YAML、JSON語言的文檔在線生成和代碼自動(dòng)生成的工具。它的優(yōu)點(diǎn)如下:

1)、它可以直接嵌入在Spring Boot項(xiàng)目中,通過開發(fā)時(shí)編寫注釋,從而自動(dòng)生成接口文檔,實(shí)現(xiàn)代碼與文檔的高度一致;
2)、可以分析接口的結(jié)構(gòu),并且還可以通過發(fā)起請(qǐng)求來驗(yàn)證接口的正確性;
3)、它提供了多種編程語言的前后端分離解決方案,支持根據(jù)定義的接口導(dǎo)出各種語言的服務(wù)端或客戶端代碼 ;
4)、它還包括了Swagger Editor,這是使用yaml語言的Swagger API的編輯器,支持導(dǎo)出yaml和json格式的接口文件;
5)、包含了Swagger UI,它可以將Swagger Editor編輯好的接口文檔以html的形式展示出來;
6)、免費(fèi)開源,支持國際化,生態(tài)豐富、社區(qū)活躍;

它的缺點(diǎn)是:

1)、對(duì)代碼有侵入性;
2)、不同項(xiàng)目的Swagger接口文檔是分離的,需要到不同的地方去找;
3)、Swagger UI展現(xiàn)出來的接口文檔缺乏分類,使用體驗(yàn)比較差;
4)、不同項(xiàng)目的接口文檔沒有權(quán)限管理,缺少M(fèi)ock;

ApiDoc

ApiDoc是一款輕量級(jí)的類似于Swagger的在線文檔生成工具。其缺點(diǎn)也類似于Swagger,接口管理、自動(dòng)測試等功能也比較弱,并且其社區(qū)、生態(tài)國際化方面都還不如Swagger。

RAP

RAP是一個(gè)可視化接口管理工具,它可以通過分析接口結(jié)構(gòu),動(dòng)態(tài)生成模擬數(shù)據(jù),校驗(yàn)真實(shí)接口正確性,圍繞接口定義,通過一系列自動(dòng)化工具提升微服務(wù)模式下的協(xié)作效率。

它的優(yōu)點(diǎn)如下:

1)、支持項(xiàng)目管理、團(tuán)隊(duì)管理、文檔版本管理;
2)、支持Mock測試數(shù)據(jù);
3)、阿里大廠出品,在阿里巴巴內(nèi)部得到實(shí)踐;
4)、支持接口檢索;
5)、可以分析接口結(jié)構(gòu),發(fā)起請(qǐng)求校驗(yàn)接口的正確性;
6)、免費(fèi)開源

缺點(diǎn)如下:

1)、文檔和接口分離,很容易出現(xiàn)不一致的現(xiàn)象;
2)、每個(gè)接口都需要手工編輯;
3)、后端采用nodejs編寫,與基于Java的Spring Cloud技術(shù)棧不一致;

DOCLever

DOCLever也是一個(gè)免費(fèi)開源的接口管理工具,它的優(yōu)點(diǎn)如下:

1)、支持項(xiàng)目管理、團(tuán)隊(duì)管理、文檔工具豐富;
2)、支持豐富的Mock測試數(shù)據(jù);
3)、用戶案例也比較豐富:滴滴、美團(tuán)、58同城、同城旅游等;
4)、支持接口檢索;
5)、可以分析接口的結(jié)構(gòu)、發(fā)起請(qǐng)求校驗(yàn)接口正確性、參數(shù)也很豐富;
6)、支持復(fù)雜場景的自動(dòng)化測試,比如獲取驗(yàn)證碼、登陸,獲取訂單列表,甚至獲取某個(gè)特定訂單詳情等上下文關(guān)聯(lián)的操作;

缺點(diǎn)如下:

1)、文檔和接口分離,很容易出現(xiàn)不一致的現(xiàn)象;
2)、每個(gè)接口都需要手工編輯;
3)、后端也是采用nodejs編寫,與Spring Cloud的Java技術(shù)棧不符;

CrapApi

優(yōu)點(diǎn)如下:

1)、支持項(xiàng)目管理、團(tuán)隊(duì)管理、文檔版本管理;
2)、支持Mock測試數(shù)據(jù);
3)、支持接口檢索;
4)、可以分析接口結(jié)構(gòu)、發(fā)起請(qǐng)求校驗(yàn)接口的正確性;
5)、支持接口監(jiān)控、設(shè)置報(bào)警規(guī)則,接口不可用時(shí)及時(shí)通知服務(wù)負(fù)責(zé)人;
6)、后端基于Java開發(fā),與Spring Cloud技術(shù)棧Java匹配;
7)、免費(fèi)開源;

缺點(diǎn):

1)、文檔和接口分離,很容易出現(xiàn)不一致的現(xiàn)象;
2)、每個(gè)接口都需要手工編輯;
3)、使用案例較少,功能不夠完善,可能會(huì)有很多坑;

Spring Cloud集成Swagger

通過對(duì)上述開源項(xiàng)目的分析,除Swagger外其余項(xiàng)目采取的都是文檔和代碼分離的方式,雖然這樣會(huì)減少對(duì)代碼的侵入,但是也會(huì)造成文檔和代碼的不一致現(xiàn)象,所以在基于Spring Cloud的微服務(wù)項(xiàng)目中,我們選擇Swagger作為微服務(wù)接口管理工具。

那么基于Spring Boot的Spring Cloud微服務(wù)該如何集成Swagger呢?

1)、在Spring Boot微服務(wù)項(xiàng)目中引入Maven依賴:

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

2)、創(chuàng)建Swagger2配置類:

@Configuration
@EnableSwagger2
@Profile("!production")
public class SwaggerConfiguration {
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("Api")
                .select()
                .apis(withClassAnnotation(RestController.class))
                .build()
                .globalOperationParameters(commonParameters())
                .apiInfo(apiInfo());
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Api")
                .version("1.0.0-SNAPSHOT")
                .build();
    }

    private List<Parameter> commonParameters() {
        List<Parameter> parameters = Lists.newArrayList();
        parameters.add(new ParameterBuilder()
                .name("war")
                .description("backdoor 在測試環(huán)境繞過鑒權(quán)")
                .modelRef(new ModelRef("string"))
                .parameterType("query")
                .required(false)
                .defaultValue("war123")
                .build());
        parameters.add(new ParameterBuilder()
                .name("uid")
                .description("backdoor 設(shè)定的用戶ID")
                .modelRef(new ModelRef("string"))
                .parameterType("query")
                .required(false)
                .defaultValue("1000053")
                .build());
        parameters.add(new ParameterBuilder()
                .name("Authorization")
                .description("生產(chǎn)環(huán)境中,需要傳遞的用戶當(dāng)前 Token")
                .modelRef(new ModelRef("string"))
                .parameterType("header")
                .required(false)
                .defaultValue("Bearer XXXXX")
                .build());
        return parameters;
    }
}

以上配置類中,我們可以通過@Profile("!production")注解指定生效的環(huán)境,如這里我們?cè)O(shè)置除在生產(chǎn)環(huán)境外,其他環(huán)境都生效。

3)、添加文檔內(nèi)容

在完成上述配置后,其實(shí)已經(jīng)可以生產(chǎn)文檔內(nèi)容了,但是這樣的文檔主要針對(duì)請(qǐng)求本身,描述的主要來源是函數(shù)的命名,多用戶并不友好,為了讓文檔更加易于閱讀和理解,我們可以通過Swagger注解來增加一些說明。這些注解主要有:

@Api:用在類上,說明該類的作用。@ApiOperation:注解來給API增加方法說明。
br/>@ApiImplicitParam:用來注解來給方法入?yún)⒃黾诱f明。<br/@ApiResponses:用于表示一組響應(yīng)。@ApiResponse:用在@ApiResponses中,一般用于表達(dá)一個(gè)錯(cuò)誤的響應(yīng)信息。<br/" rel="nofollow">br/>@ApiResponse:用在@ApiResponses中,一般用于表達(dá)一個(gè)錯(cuò)誤的響應(yīng)信息。<br/@ApiModel:描述一個(gè)Model的信息(一般用在請(qǐng)求參數(shù)無法使用@ApiImplicitParam注解進(jìn)行描述的時(shí)候)。

接下來,我們通過一個(gè)實(shí)際的微服務(wù)接口定義案例來演示下:

@Api(value = "運(yùn)維端系統(tǒng)用戶層外部接口", description = "用于組裝直接面向運(yùn)維App端相關(guān)服務(wù)")
@RestController
@Slf4j
public class OperationUserController {

    @Autowired
    OperationUserService operationUserServiceImpl;

    @ApiOperation(value = "運(yùn)維端用戶注冊(cè)", httpMethod = "POST")
    @RequestMapping(value = "/userRegister", method = RequestMethod.POST)
    public APIResponse sysUserRegister(@RequestParam(value = "mobileNo") String mobileNo,
            @RequestParam(value = "email") String email,
            @RequestParam(value = "nickName", required = false) String nickName,
            @RequestParam(value = "idName") String idName, @RequestParam(value = "idType") String idType,
            @RequestParam(value = "idNo") String idNo, @RequestParam(value = "gender") String gender,
            @RequestParam(value = "password") String password, @RequestParam(value = "verifyCode") String verifyCode,
            @RequestParam(value = "creator") String creator) {
        UserRegisterReqVo userRegisterReqVo = UserRegisterReqVo.builder().mobileNo(mobileNo).email(email)
                .nickName(nickName).idName(idName).idType(idType).idNo(idNo).gender(gender).passwd(password)
                .passcode(verifyCode).creator(creator).build();
        UserRegisterResVo userRegisterResVo;
        try {
            userRegisterResVo = operationUserServiceImpl.userRegister(userRegisterReqVo);
        } catch (BizException e) {
            log.error(e.toString() + "_" + e.getMessage(), e);
            return APIResponse.error(e.getCode(), e.getMessage());
        } catch (Exception e) {
            log.error(e.toString() + "_" + e.getMessage(), e);
            return APIResponse
                    .error(ApiResultStatus.INTERNAL_SERVER_ERROR.getApiResultStatus(),
                            ApiResultStatus.INTERNAL_SERVER_ERROR.getMessageResourceName());
        }
        return APIResponse
                .success(ApiResultStatus.SUCCESS.getApiResultStatus(), ApiResultStatus.SUCCESS.getMessageResourceName(),
                        userRegisterResVo);
    }
}

以上我們?cè)谖⒎?wù)下定義了一個(gè)用戶注冊(cè)接口,此時(shí)啟動(dòng)微服務(wù),然后輸入微服務(wù)的IP+端口+/swagger-ui.html,就可以看到Swagger-UI了。通過Swagger-UI我們就可以校驗(yàn)的方式測試接口了,同時(shí)因?yàn)榻涌谧侄味荚赨I有說明和暫時(shí),并且是與實(shí)際代碼完全一致的,所以在對(duì)接時(shí)基于這些接口定義進(jìn)行對(duì)接就可以了!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI