基于CSE的微服务工程实践-Native API先行

网友投稿 552 2022-05-30

[Open API]( https://swagger.io/docs/specification/about/) 采用Swagger进行描述,能够灵活的支持RPC风格和REST风格的接口定义,并且考虑了跨平台接口定义要求。使用Swagger进行接口开发代码,需要熟悉这个规范,并理解和代码逻辑之间的约束关系,对于一些初步接触的设计人员来讲,这个过程会比较痛苦。 在不写Swagger的情况下,CSE推荐设计者可以先结合自己熟悉的开发语言,使用接口的方式定义RPC或者REST接口。本文以JAVA语言为例,描述设计者如何定义接口。

微服务架构下,所有微服务之间都通过暴露REST接口进行访问。从管理/设计者的视角,通常期望系统的边界清晰,规格可控,因此接口的开发是独立受控的。早期JAVA标准,比如JSR Validation API等,都通过API包的方式供实现者使用。借鉴这个思路,设计者在设计微服务的时候,也可以将微服务的接口在独立的jar包项目中提供,实现者应用这个jar包即可。

使用CSE设计公共的接口,建议设计者提供两个类:

·         Service: 一个JAVA接口,这个接口可以由开发者实现。

·         Endpoint: 接口的REST描述。

举个例子,Service定义了开发者如何实现这个服务,开发者可以看不到REST标签,不用思考和HTTP的映射关系。

public interface UserService {   public SessionInfo login(String userName,       String password);     public SessionInfo getSession(String sessionId);     public String ping(String message); }

Endpoint定义这个服务对外暴露的REST接口,可以采用Spring MVC或者JAX RS两种方式进行描述。Endpoint是一个具体实现类,但是其实现逻辑,全部代理给Service的实现。

基于CSE的微服务工程实践-Native API先行

@RestSchema(schemaId = "user") @RequestMapping(path = "/") @SwaggerDefinition(info = @Info(description = "用户认证、会话等管理", title = "用户管理接口", version = "v1"), basePath = "/") public class UserEndpoint {   @Autowired   private UserService userService;     @PostMapping(path = "/v1/user/login", produces = MediaType.APPLICATION_JSON_VALUE)   @ApiOperation(value = "登录")   public SessionInfo login(@RequestParam(name = "userName") String userName,       @RequestParam(name = "password") String password) {     return userService.login(userName, password);   }     @GetMapping(path = "/v1/user/session", produces = MediaType.APPLICATION_JSON_VALUE)   @ApiOperation(value = "查询会话")   public SessionInfo getSession(@RequestParam(name = "sessionId") String sessionId) {     return userService.getSession(sessionId);   }     @GetMapping(path = "/v1/user/ping", produces = MediaType.APPLICATION_JSON_VALUE)   @ApiOperation(value = "系统测试接口")   public String ping(@RequestParam(name = "message") String message) {     return userService.ping(message);   } }

[porter例子]( https://github.com/huaweicse/cse-java-chassis-samples/tree/master/porter )  展现了这个设计思路。

接口定义的一些注意事项和讨论

上诉方式是在实践中探索的一种比较好的接口组织形式,当然可以有其他各种形式。比较常见的辩论形式有直接定义Endpoint接口,所有的标签写到Endpoint上,开发者只需要实现Endpoint即可。这种形式看起来更加的简洁,但是CSE没有提供这种开发方式的支持,即REST的标签必须在实现类上,不能出现在实现类的父类或者实现接口上。CSE考虑过是否提供这种开发模式的支持,后面放弃了。主要的原因是因为JAVA在语言机制上,并没有提供annotation的继承机制(class的annotation可以通过@Inherited继承,但是Method没有)。当然通过反射遍历也是可以获取到父类的annotation的,把技术建立在一个不可靠的技术基础上,会带来大量的问题。当然放弃这种模式还有其他原因,关于是否共享Interface供服务实现者实现和客户端开发引用存在大量的争论,感兴趣的开发者可以搜索网络,查询这方面的设计讨论。

注意事项

由于@RestSchema也是一个bean,在所有微服务的接口定义都在一个common jar包里面时,要避免一个微服务加载所有的bean。所以需要把不同服务的定义放到不同的package里面,通过ComponentScan控制加载范围或者创建不同的jar包,完全不引用。

API网关 APIG CSE 契约

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:容器化上云之可行性评估
下一篇:《 Kubernetes进阶实战》一2.2部署Kubernetes集群
相关文章