Spring Cloud如何提供API给客户端

时间:2022-05-06
本文章向大家介绍Spring Cloud如何提供API给客户端,主要内容包括关于第一个问题中的API是各个微服务下的Controller?、关于第一个问题中的是否需要统一的一个工程,在里面封装其他微服务的controller?、一. API网关直接转发到博客服务中、二.增加聚合服务层、三.调用方自行去获取各个数据、总结、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

现在越来越多的公司开始拥抱Spring Cloud了,很多Java方向的同学也开始积极的学习Spring Cloud,其实这边还有一个问题就是说:虽然大家学了Eureka,Ribbon,Hystrix,Zuul,Feign等等,但是要运用到实际的项目中去还是有些难度的。

微服务难就难在服务的拆分上,框架只是工具,很多人都会用,服务拆分,服务之间的关系这些都是在拆分时候需要考虑的事情。

今天就有一位同学给我发邮件,咨询我下面2个问题:

下面以我自己的经验来做一些解答,仅供参考:

关于第一个问题中的API是各个微服务下的Controller?

我们所说的API其实就是一个接口,大部分都是用Spring MVC方式去开发的,也就是Controller中的一个加了注解的方法,注解就是我们常用的那几个:

  • @RequestMapping
  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping

关于第一个问题中的是否需要统一的一个工程,在里面封装其他微服务的controller?

这种其实也没有固定的模式,大部分是直接通过API网关转发到你的业务服务上

以猿天地这样的博客网站的业务类举例:

有一个业务功能,当我查看具体的博客文章的时候,需要返回的信息如下:

  • 博文标题
  • 发布时间
  • 作者
  • 标签
  • 阅读数量
  • 评论信息
  • 作者信息(昵称,介绍)

这个时候我们这个查看文章的接口其实就涉及到了3部分的数据,文章本身的信息,评论信息,作者的信息

就是有3个服务,用户服务,博客服务,评论服务

那么问题来了,涉及到多个服务之前的交互,其实跟上面那位同学问我的是一样的问题,是否需要统一工程,组装其他服务?是否可以相互调用?

这种的话我推荐2种实现方式:

一. API网关直接转发到博客服务中

我们这个API就是一个获取博文信息的接口,主体肯定是博客服务,在博客服务中有一个博文信息的接口,在接口中去调用用户服务提供的用户信息接口,还要去调用评论服务中博文的评论信息,下面看伪代码:

@GetMapping("/blog/detail/{id}")
public BlogInfo blogInfo(@PathVariable("id") Long id) {

    // 获取博客信息
    Blog blog = blogService.getById(id);

    // 获取用户信息
    UserInfo userInfo = userFeignClient.getUserInfo(blog.getUserId());

    // 获取评论信息
    CommentInfo commentInfo = commentFeignClient.getCommentInfo(id);

    return 组装所有信息返回。

}

二.增加聚合服务层

集合服务层也就是上面那位同学说的是不是需要有一个统一的工程来做组装服务的事情,这个就是说我们博客服务还是提供基础的博客信息,单独加一个业务的聚合服务用来组装这些信息统一返回给调用方,伪代码如下:

@GetMapping("/blog/detail/{id}")
public BlogInfo blogInfo(@PathVariable("id") Long id) {

    // 获取博客信息
    Blog blog = blogFeignClient.getById(id);

    // 获取用户信息
    UserInfo userInfo = userFeignClient.getUserInfo(blog.getUserId());

    // 获取评论信息
    CommentInfo commentInfo = commentFeignClient.getCommentInfo(id);

    return 组装所有信息返回。

}

数据都是远程调用的,当然这边你可以并行去调用,还有一种方式就是聚合操作在API网关中进行,这种方案也是可行的,我建议还是不要在网关中做,API网关尽量简单,只转发,增加聚合服务层是不错的选择。

如果你的服务治理是用dubbo构建的,聚合服务层也是比较好的方法,将dubbo服务聚合统一提供http接口给外部调用。

三.调用方自行去获取各个数据

还有一种方式的话就是调用方自己去分别调用博客接口,评论接口,用户接口,这样的话接口只需要关注自己本身的数据,把组装的问题交给的使用方,这种一般用的比较少,最好是一次性将要用的数据返回给调用方,反复调用特别是在移动端,请求太多了,浪费流量。

总结

至于要怎么去组装数据,还是得你自己来定,可以将组装放在对应的业务服务中,也可以单独增加一个聚合服务来组装,也可以让客户端自己去组装。

服务之间肯定是可以相互调用的,要是不能相互调用,那么你拆开还有什么意义,用Feign来调用服务接口,你就把它当做Service之间的调用即可。