nats rpc 服务暴露rest api 的处理
以前我简单说过,就是通过动态注册controller 就可以了,以下是一个演示
具体处理
- 参考处理
就是自己基于定义nats rpc 的RestApiAbstractServiceHandler,包含一个基本实现,同时对于注册服务基于自定义注解,为了方便处理,可以直接复用spring http request 的一些东西
public abstract class RestApiAbstractServiceHandler<T extends BaseMessage> extends AbstractServiceHandler<T> {
public <R> R defaultRestApiHandler(T demoMessage, HttpHeaders httpHeaders){
return restApiHandler(demoMessage, httpHeaders);
}
public <R> R restApiHandler(T baseMessage, HttpHeaders headers) {
Method actionMethod = actionMethod(baseMessage);
Headers natsHeaders;
if (headers != null) {
natsHeaders = new Headers();
headers.forEach((key, values) -> {
for (String value : values) {
natsHeaders.add(key, value);
}
});
} else {
natsHeaders = null;
}
boolean continueProcess = beforeHandle(actionMethod, baseMessage, natsHeaders);
if (continueProcess) {
Object result = actionMethodExecute(actionMethod, this, baseMessage, natsHeaders);
afterHandle(actionMethod, result, natsHeaders);
return (R) result;
}
return null;
}
}
- 动态注册
public void registerRestApis() {
serviceHandlers.forEach(serviceHandler -> {
// 获取实际类,避免动态代理的
Class<?> targetClass =
AopProxyUtils.ultimateTargetClass(serviceHandler);
Method[] methods = targetClass.getDeclaredMethods();
Arrays.stream(methods).forEach(method -> {
// 过滤bridge方法,不然会有重复的问题
if(method.isBridge()){
return;
}
ServiceMapping serviceMapping = method.getAnnotation(ServiceMapping.class);
if (serviceMapping == null) {
return;
}
if (method.getDeclaringClass() != targetClass) {
return;
}
// 结合注解,动态注册controller
RequestMappingInfo mapping = RequestMappingInfo
.paths(serviceMapping.path())
.methods(Arrays.stream(serviceMapping.method()).map(item -> methodutils.str2RequestMethod(item)).toArray(RequestMethod[]::new))
.build();
Method handlerMethod = method;
requestMappingHandlerMapping.registerMapping(mapping, serviceHandler, handlerMethod);
});
});
}
- 业务使用
代码截取了部分,核心演示就是可以同时暴露,还可以使用现有的http request 处理
@ResponseBody
@ServiceMapping(
name = "defaultRestApiHandler",
path = {"/api/default/rest/"},
method = {"POST"},
version = "1.0.0"
)
@Override
public Object defaultRestApiHandler(@RequestBody DemoMessage demoMessage, @Parameter(hidden = true) HttpHeaders httpHeaders) {
return super.defaultRestApiHandler(demoMessage, httpHeaders);
}
@ResponseBody
@ServiceMapping(path = {"/appdemo/{id}"},method = {"POST"})
public DemoMessage echoDemo(@RequestBody DemoMessage demoMessage, @PathVariable("id") String id, @RequestHeader(name = "token", required = false) String token){
return echoDemo(demoMessage, new Headers());
}
@ResponseBody
@ServiceMapping(path = {"/api/gw/{id}"},method = {"POST"})
public DemoMessage apiGateway(@RequestBody DemoMessage demoMessage, @PathVariable("id") String id, @Parameter(hidden = true) @RequestHeader(required = false) HttpHeaders httpHeaders){
return echoDemo(demoMessage, new Headers());
}
说明
以上代码是我nats-rpc-springboot-starter的内部处理机制,详细代码可以看是实际源码,机制比较简单
参考资料
https://github.com/rongfengliang/nats-rpc-springboot-starter
浙公网安备 33010602011771号