首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Springboot外部api调用请求和数据库中的响应捕获

Springboot外部api调用请求和数据库中的响应捕获
EN

Stack Overflow用户
提问于 2020-02-01 04:47:13
回答 2查看 2.8K关注 0票数 0

在我的后端应用程序(springboot,java8)中,我将进行多个外部api调用。

下面是我的示例代码,这是我试图捕获每个外部api调用的请求和响应的方式。在例外情况下,我将将状态存储为“失败”。

在我的项目中,将在新的第三方api集成上添加多个模块,因此在每个模块中,对于每个不同的外部api调用,我都必须捕获像这样的所有请求和响应。我对下面的方法不满意。请提出解决这一问题的最佳方法。

示例服务层方法

代码语言:javascript
复制
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调用的示例域

代码语言:javascript
复制
@Document("api_calls")
@Builder
@Data
public class ApiCall {

    @Id
    private String id;

    private String clientId;

    private String status;

    private Object requestPayload;

    private Object responsePayload;

}
EN

回答 2

Stack Overflow用户

发布于 2020-02-01 08:09:42

您可以使用Spring来解决这个横切关注点。

假设ExternalApiCallService是一个spring,下面的代码将拦截所有callExternalApi1()并将其记录到数据库中。

代码语言:javascript
复制
@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.对方面代码进行了验证,并在未经过测试的情况下包含了该逻辑。请作出所需的更正

理想情况下,应将原始方法简化为以下内容

代码语言:javascript
复制
public ResponseDTOFromExternalApi externalApiCallServiceMethod(String clientId, RequestDTO requestDTO) {

       return toDTO(externalApiCallService.callExternalApi1(prepareExternalApiRequestObjFromRequestDTO(requestDTO)));
}

关于Spring 这里的更多信息

更新:重新考虑一下,如果所有外部api调用都是通过一个方法(例如ExternalApiCallService.callExternalApi1() )进行的,那么这个日志逻辑可以移动到这个共同点,不是吗?

票数 0
EN

Stack Overflow用户

发布于 2020-02-01 11:26:48

Spring的WebClient已经能够通过添加交换过滤器来记录所有请求和响应数据。

通过在网络请求中使用它,只需要在mongodb中写入这些信息。

下面是关于日志记录请求和响应的教程:https://www.baeldung.com/spring-log-webclient-calls

干杯

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60014084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档