Spring Cloud微服务接口这么多怎么调试?



导读
html


今天和你们聊一下Spring Cloud微服务下服务接口调试及管理的话题!咱们知道在微服务架构下,软件系统会被拆分红不少个独立运行的服务,而这些服务间须要交互通讯,就须要定义各类各样的服务接口。具体来讲,在基于Spring Cloud的微服务模式中,各个微服务会基于Spring MVC的Controller定义多个该微服务须要向外部发布的接口。java


根据各个微服务功能边界定义的不一样,有些微服务会提供与具体业务相关的接口,如支付接口、帐户接口等;而有些微服务则会提供一些公共性质的服务接口,如短信接口、统一认证接口之类。而这些微服务每每又是由多个不一样的团队在开发维护,传统方式下服务接口的定义每每须要服务提供方提供良好的、可阅读性比较高的接口文档才能够比较方便地对接和测试,而事实上,随着时间的推移、人员的迭代更新,不少状况下这些早期的接口文档每每很快就会由于无人维护而过期,即使不过期,微服务模式下这样的方式也会由于服务接口文档太多而让开发人员显得抓狂!node


那么有没有一种更便捷地方式,可让开发接口的同时,自动就能生成与服务接口高度一致的文档来呢?答案是有的,接下来就和你们一块儿聊聊到底有什么样方式可让微服务的接口管理变得更加容易些!web


接口管理方式介绍
spring


事实上,市面上已经有多种开源项目提供了这样的支持!如:Swagger、ApiDoc、RAP、DOCLever、CrapApi等,这些项目都提供了对于Api在线文档的管理功能,那么在Spring Cloud体系中哪种方式更加适合呢?下面,咱们一块儿来对比下这些项目的优缺点。数据库


Swagger编程


Swagger是一款基于YAML、JSON语言的文档在线生成和代码自动生成的工具。它的优势以下:json

1)、它能够直接嵌入在Spring Boot项目中,经过开发时编写注释,从而自动生成接口文档,实现代码与文档的高度一致;
2)、能够分析接口的结构,而且还能够经过发起请求来验证接口的正确性;
3)、它提供了多种编程语言的先后端分离解决方案,支持根据定义的接口导出各类语言的服务端或客户端代码 ;
4)、它还包括了Swagger Editor,这是使用yaml语言的Swagger API的编辑器,支持导出yaml和json格式的接口文件;
5)、包含了Swagger UI,它能够将Swagger Editor编辑好的接口文档以html的形式展现出来;
6)、免费开源,支持国际化,生态丰富、社区活跃;
后端


它的缺点是:api

1)、对代码有侵入性;
2)、不一样项目的Swagger接口文档是分离的,须要到不一样的地方去找;
3)、Swagger UI展示出来的接口文档缺少分类,使用体验比较差;
4)、不一样项目的接口文档没有权限管理,缺乏Mock;


官网地址:https://swagger.io/


ApiDoc


ApiDoc是一款轻量级的相似于Swagger的在线文档生成工具。其缺点也相似于Swagger,接口管理、自动测试等功能也比较弱,而且其社区、生态国际化方面都还不如Swagger。


官网地址:http://apidocjs.com/


RAP


RAP是一个可视化接口管理工具,它能够经过分析接口结构,动态生成模拟数据,校验真实接口正确性,围绕接口定义,经过一系列自动化工具提高微服务模式下的协做效率。


它的优势以下:

1)、支持项目管理、团队管理、文档版本管理;
2)、支持Mock测试数据;
3)、阿里大厂出品,在阿里巴巴内部获得实践;
4)、支持接口检索;
5)、能够分析接口结构,发起请求校验接口的正确性;
6)、免费开源


缺点以下:

1)、文档和接口分离,很容易出现不一致的现象;
2)、每一个接口都须要手工编辑;
3)、后端采用nodejs编写,与基于Java的Spring Cloud技术栈不一致;


官网地址:http://rapapi.org/org/index.do


DOCLever


DOCLever也是一个免费开源的接口管理工具,它的优势以下:

1)、支持项目管理、团队管理、文档工具丰富;
2)、支持丰富的Mock测试数据;
3)、用户案例也比较丰富:滴滴、美团、58同城、同城旅游等;
4)、支持接口检索;
5)、能够分析接口的结构、发起请求校验接口正确性、参数也很丰富;
6)、支持复杂场景的自动化测试,好比获取验证码、登录,获取订单列表,甚至获取某个特定订单详情等上下文关联的操做;


缺点以下:

1)、文档和接口分离,很容易出现不一致的现象;
2)、每一个接口都须要手工编辑;
3)、后端也是采用nodejs编写,与Spring Cloud的Java技术栈不符;


官网地址:http://doclever.cn


CrapApi


优势以下:

1)、支持项目管理、团队管理、文档版本管理;
2)、支持Mock测试数据;
3)、支持接口检索;
4)、能够分析接口结构、发起请求校验接口的正确性;
5)、支持接口监控、设置报警规则,接口不可用时及时通知服务负责人;
6)、后端基于Java开发,与Spring Cloud技术栈Java匹配;
7)、免费开源;


缺点:

1)、文档和接口分离,很容易出现不一致的现象;
2)、每一个接口都须要手工编辑;
3)、使用案例较少,功能不够完善,可能会有不少坑;


官网地址:http://api.crap.cn


Spring Cloud集成Swagger


经过对上述开源项目的分析,除Swagger外其他项目采起的都是文档和代码分离的方式,虽然这样会减小对代码的侵入,可是也会形成文档和代码的不一致现象,因此在基于Spring Cloud的微服务项目中,咱们选择Swagger做为微服务接口管理工具。


那么基于Spring Boot的Spring Cloud微服务该如何集成Swagger呢?


1)、在Spring Boot微服务项目中引入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)、建立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 在测试环境绕过鉴权")
                .modelRef(new ModelRef("string"))
                .parameterType("query")
                .required(false)
                .defaultValue("war123")
                .build());
        parameters.add(new ParameterBuilder()
                .name("uid")
                .description("backdoor 设定的用户ID")
                .modelRef(new ModelRef("string"))
                .parameterType("query")
                .required(false)
                .defaultValue("1000053")
                .build());
        parameters.add(new ParameterBuilder()
                .name("Authorization")
                .description("生产环境中,须要传递的用户当前 Token")
                .modelRef(new ModelRef("string"))
                .parameterType("header")
                .required(false)
                .defaultValue("Bearer XXXXX")
                .build());
        return parameters;
    }
}


以上配置类中,咱们能够经过@Profile("!production")注解指定生效的环境,如这里咱们设置除在生产环境外,其余环境都生效。


3)、添加文档内容

在完成上述配置后,其实已经能够生产文档内容了,可是这样的文档主要针对请求自己,描述的主要来源是函数的命名,多用户并不友好,为了让文档更加易于阅读和理解,咱们能够经过Swagger注解来增长一些说明。这些注解主要有:

@Api:用在类上,说明该类的做用。
@ApiOperation:注解来给API增长方法说明。
@ApiImplicitParams : 用在方法上包含一组参数说明。
@ApiImplicitParam:用来注解来给方法入参增长说明。
@ApiResponses:用于表示一组响应。
@ApiResponse:用在@ApiResponses中,通常用于表达一个错误的响应信息。
@ApiModel:描述一个Model的信息(通常用在请求参数没法使用@ApiImplicitParam注解进行描述的时候)。

接下来,咱们经过一个实际的微服务接口定义案例来演示下:


@Api(value = "运维端系统用户层外部接口", description = "用于组装直接面向运维App端相关服务")
@RestController
@Slf4j
public class OperationUserController {

    @Autowired
    OperationUserService operationUserServiceImpl;

    @ApiOperation(value = "运维端用户注册", 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);
    }
}


以上咱们在微服务下定义了一个用户注册接口,此时启动微服务,而后输入微服务的IP+端口+/swagger-ui.html,就能够看到Swagger-UI了,以下:



经过Swagger-UI咱们就能够校验的方式测试接口了,同时由于接口字段都在UI有说明和暂时,而且是与实际代码彻底一致的,因此在对接时基于这些接口定义进行对接就能够了!


推荐阅读:

Spring Boot集成Flyway实现数据库版本控制?

Spring Cloud微服务如何实现熔断降级?

Spring Cloud微服务如何设计异常处理机制?

Spring Cloud微服务中网关服务是如何实现的?(Zuul篇)

Spring Cloud是怎么运行的?

基于SpringCloud的微服务架构演变史?

Spring Boot究竟是怎么运行的,你知道吗?


—————END—————



识别图片二维码,关注“无敌码农”获取精彩内容

本文分享自微信公众号 - 无敌码农(jiangqiaodege)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索