实现nats rpc rest api gateway
主要说明下如何实现,具体就是基于现有的框架,实现基于service 提及msg 进行转发,处理比较简单
包装
主要说明下服务的
- 定义rest 暴露处理 RestApiAbstractServiceHandler 就是转发请求
public <R> R defaultRestApiHandler(String serviceName, String prefix, String serviceEndpoint, T demoMessage, HttpHeaders httpHeaders) {
return restApiHandler(serviceName, prefix, serviceEndpoint, demoMessage, httpHeaders);
}
public boolean beforeRestApiHandler(String serviceName, String prefix, String serviceEndpoint, T baseMessage, HttpHeaders headers) {
return true;
}
public void afterRestApiHandler(String serviceName, String prefix, String serviceEndpoint, T baseMessage, HttpHeaders headers, Object result) {
}
public <R> R restApiHandler(String serviceName, String prefix, String serviceEndpoint, T baseMessage, HttpHeaders headers) {
Headers natsHeaders;
if (headers != null) {
natsHeaders = new Headers();
headers.forEach((key, values) -> {
for (String value : values) {
natsHeaders.add(key, value);
}
});
} else {
natsHeaders = null;
}
String fullServiceEndpoint = String.format("%s.svc.%s.%s", serviceName, prefix, serviceEndpoint);
if (beforeRestApiHandler(serviceName, prefix, serviceEndpoint, baseMessage, headers)) {
byte[] payload = serializeMessage(this.getObjectMapper(), baseMessage);
Object result = NatsRpcCall.call(this.getConnection(), this.getObjectMapper(), fullServiceEndpoint, payload, natsHeaders);
afterRestApiHandler(serviceName, prefix, serviceEndpoint, baseMessage, headers, result);
return (R) result;
}
return null;
}
- 代码
服务格式/api/gw/rest/{servicename}/{prefix}/{serviceendpoint}
@Component
public class NatsRpcServiceHandler extends RestApiAbstractServiceHandler<BaseMessage> {
private Connection connection;
private ObjectMapper objectMapper;
public NatsRpcServiceHandler(ObjectMapper objectMapper, Connection connection) {
this.objectMapper = objectMapper;
this.connection = connection;
}
@Override
public Connection getConnection() {
return this.connection;
}
@Override
public ObjectMapper getObjectMapper() {
return this.objectMapper;
}
@Override
public BaseMessage defaultMessageHandler(BaseMessage demoMessage, Headers headers) {
return demoMessage;
}
@ResponseBody
@ServiceMapping(
name = "defaultRestApiHandler",
path = {"/api/gw/rest/{servicename}/{prefix}/{serviceendpoint}"},
method = {"POST"},
version = "1.0.0"
)
@Override
public Object defaultRestApiHandler(@PathVariable(name = "servicename") String serviceName,
@PathVariable(name = "prefix") String prefix,
@PathVariable(name = "serviceendpoint") String serviceEndpoint,
@RequestBody BaseMessage demoMessage,
@Parameter(hidden = true) @RequestHeader HttpHeaders httpHeaders) {
return super.defaultRestApiHandler(serviceName,prefix,serviceEndpoint, demoMessage, httpHeaders);
}
}
- 内部处理
因为提供了bean,核心就是对于@ServiceMapping 注解的处理,然后动态注册controller 就可以了
public void registerRestApis() {
serviceHandlers.forEach(serviceHandler -> {
Class<?> targetClass =
AopProxyUtils.ultimateTargetClass(serviceHandler);
Method[] methods = targetClass.getMethods();
Arrays.stream(methods).forEach(method -> {
if(method.isBridge()){
return;
}
ServiceMapping serviceMapping = method.getAnnotation(ServiceMapping.class);
if (serviceMapping == null) {
return;
}
if (method.getDeclaringClass() != targetClass) {
return;
}
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);
});
});
}
参考api 效果

说明
整体处理很简单,核心是动态注册,以及自动bena注入(包装为starter),详细代码参考github
参考资料
https://github.com/rongfengliang/nats-rpc-springboot-starter
浙公网安备 33010602011771号