在我的后端应用程序(springboot,java8)中,我将进行多个外部api调用。
下面是我的示例代码,这是我试图捕获每个外部api调用的请求和响应的方式。在例外情况下,我将将状态存储为“失败”。
在我的项目中,将在新的第三方api集成上添加多个模块,因此在每个模块中,对于每个不同的外部api调用,我都必须捕获像这样的所有请求和响应。我对下面的方法不满意。请提出解决这一问题的最佳方法。
示例服务层方法
public ResponseDTOFromExternalApi externalApiCallServiceMethod(String clientId, RequestDTO requestDTO) {
ExternalApiCallRequestObj externalApiCallRequestObj = prepareExternalApiRequestObjFromRequestDTO(requestDTO);
ApiCall apiCall = ApiCall.builder()
.clientId(clientId)
.status("SUBMITTED")
.requestPayload(externalApiCallRequestObj)
.build();
apiCall = apiCallRepository.save(apiCall);
ExternalApiCallReponseObj externalApiCallReponseObj = externalApiCallService.callExternalApi1(externalApiCallRequestObj);
apiCall = apiCallRepository.findById(apiCall.getId());
apiCall.setResponsePayload(externalApiCallReponseObj);
apiCall.setStatus("COMPLETED");
apiCallRepository.save(apiCall);
return toDTO(externalApiCallReponseObj);
}api调用的示例域
@Document("api_calls")
@Builder
@Data
public class ApiCall {
@Id
private String id;
private String clientId;
private String status;
private Object requestPayload;
private Object responsePayload;
}发布于 2020-02-01 08:09:42
您可以使用Spring来解决这个横切关注点。
假设ExternalApiCallService是一个spring,下面的代码将拦截所有callExternalApi1()并将其记录到数据库中。
@Component
@Aspect
public class ExternalCallLoggerAspect {
@Autowired
ApiCallRepository apiCallRepository;
@Pointcut("execution(* *..ExternalApiCallService.callExternalApi1(..))")
public void externalApiCallService(){}
@Around("externalApiCallService() && args(request)")
public ExternalApiCallReponseObj logCalls(ProceedingJoinPoint pjp,ExternalApiCallRequestObj request){
Object result=null;
String status = "COMPLETED";
ExternalApiCallReponseObj response = null;
// Build the apiCall from request
ApiCall apiCall = ApiCall.builder()
.clientId(clientId)
.status("SUBMITTED")
.requestPayload(request)
.build();
//save the same to db
apiCall = apiCallRepository.save(apiCall);
// Proceed to call the external Api and get the result
try {
result = pjp.proceed();
} catch (Throwable e) {
status = "FAILED";
}
//Update the response
apiCall = apiCallRepository.findById(apiCall.getId());
apiCall.setStatus(status);
apiCallRepository.save(apiCall);
if(result != null) {
response = (ExternalApiCallReponseObj)result;
apiCall.setResponsePayload(response);
}
//continue with response
return response;
}
}备注
1.有一个名为ExternalApiCallReponseObj的错误
2.对方面代码进行了验证,并在未经过测试的情况下包含了该逻辑。请作出所需的更正
理想情况下,应将原始方法简化为以下内容
public ResponseDTOFromExternalApi externalApiCallServiceMethod(String clientId, RequestDTO requestDTO) {
return toDTO(externalApiCallService.callExternalApi1(prepareExternalApiRequestObjFromRequestDTO(requestDTO)));
}关于Spring 这里的更多信息
更新:重新考虑一下,如果所有外部api调用都是通过一个方法(例如ExternalApiCallService.callExternalApi1() )进行的,那么这个日志逻辑可以移动到这个共同点,不是吗?
发布于 2020-02-01 11:26:48
Spring的WebClient已经能够通过添加交换过滤器来记录所有请求和响应数据。
通过在网络请求中使用它,只需要在mongodb中写入这些信息。
下面是关于日志记录请求和响应的教程:https://www.baeldung.com/spring-log-webclient-calls
干杯
https://stackoverflow.com/questions/60014084
复制相似问题