【问题标题】:How to set header variables in GraphQL-SPQR如何在 GraphQL-SPQR 中设置标头变量
【发布时间】:2020-03-22 09:07:57
【问题描述】:

我正在使用 GraphQL-SPQR 和 Spring Boot 运行 GraphQL API。

目前,我正在抛出 RuntimeExceptions 以返回 GraphQL 错误。我有一个customExceptionHandler,它实现了DataFetcherExceptionHandler,它以正确的格式返回错误,如下所示:

class CustomExceptionHandler : DataFetcherExceptionHandler {
    override fun onException(handlerParameters: DataFetcherExceptionHandlerParameters?): DataFetcherExceptionHandlerResult {


        // get exception
        var exception = handlerParameters?.exception
        val locations = listOf(handlerParameters?.sourceLocation)
        val path = listOf(handlerParameters?.path?.segmentName)

        // create a GraphQLError from your exception
        if (exception !is GraphQLError) {
            exception = CustomGraphQLError(exception?.localizedMessage, locations, path)
        }

        // cast to GraphQLError
        exception as CustomGraphQLError

        exception.locations = locations
        exception.path = path

        val errors = listOf<GraphQLError>(exception)

        return DataFetcherExceptionHandlerResult.Builder().errors(errors).build()
    }
}

我使用CustomExceptionHandler 如下(在我的主应用程序类中):

@Bean
    fun graphQL(schema: GraphQLSchema): GraphQL {
        return GraphQL.newGraphQL(schema)
                .queryExecutionStrategy(AsyncExecutionStrategy(CustomExceptionHandler()))
                .mutationExecutionStrategy(AsyncSerialExecutionStrategy(CustomExceptionHandler()))
                .build()
    }

我想为与异常对应的 UUID 设置一个标头变量,用于记录目的。我该怎么做?

更好的是,是否可以创建一个 Spring Bean 将 UUID 放在所有查询和突变的标头中?

谢谢!

【问题讨论】:

    标签: spring-boot kotlin graphql graphql-java graphql-spqr


    【解决方案1】:

    当你使用 spring boot 时,有两种选择:

    • 您正在使用 spring boot graphql spqr starter(它自带控制器来处理所有 graphQL 请求)
    • 您使用的是普通的 graphql-spqr 并拥有自己的控制器来处理 GraphQL 请求

    无论如何,你有几个选择:

    将您的 CustomExceptionHandler 设为 Spring Bean 并自动装配 HttpServletResponse

    这可能是最简单的方法——它可能在任何情况下都可以工作:你可以简单地将你的 CustomExceptionHandler 设为 Spring bean 并让它自动装配 HttpServletRequest——在处理程序方法中,你可以将它设置为任何你希望它是。这是Java中的一些虚拟代码(对不起,我对Kotlin不够精通):

    @Component
    class CustomExceptionHandler implements DataFetcherExceptionHandler {
        private final HttpServletResponse response; 
    
        public CustomExceptionHandler(HttpServletResponse response) {
            this.response = response; 
        }
    
        @Override
        public DataFetcherExceptionHandlerResult onException(DataFetcherExceptionHandlerParameters handlerParameters) {
            response.setHeader("X-Request-ID", UUID.randomUUID().toString());
            // ... your actual error handling code
        }
    }
    

    这会起作用,因为 spring 会意识到每个请求的 HttpServletRequest 都不同。因此,它将向您的错误处理程序注入一个动态代理,该代理将指向每个请求的实际 HttpServletResponse 实例。

    我会说,这不是最优雅的方式,但它肯定会解决您的问题。

    对于 graphql-spqr spring boot starter

    有一个default controller implementation 用于使用此启动器的项目中。该控制器将处理您收到的每个 graphql 请求。您可以通过实现自己的GraphQLExecutor 并使其成为spring bean 来自定义它。该执行器负责调用 GraphQL 引擎,将参数传入并输出响应。这是the default implementation,您可能希望以此为基础。

    与之前的解决方案类似,您可以在该类中自动装配 HttpServletResponse 并设置 HTTP 响应标头。

    该解决方案将允许您决定是在所有情况下设置请求 ID,还是仅在特定错误情况下设置请求 ID。 (graphql.execute 返回一个对象,您可以从中获取信息是否存在以及存在哪些错误)

    在没有 spring boot starter 的情况下使用 graphql-spqr 时

    找到您的 GraphQL 控制器,为 HttpServletRequest 类型的该方法添加一个参数 - 然后根据您的喜好添加标头(请参阅上一节中的一些更具体的建议)

    【讨论】:

      猜你喜欢
      • 2019-10-12
      • 2021-10-26
      • 2019-07-22
      • 2018-10-07
      • 2020-08-19
      • 2020-03-31
      • 1970-01-01
      • 1970-01-01
      • 2021-06-03
      相关资源
      最近更新 更多