简体   繁体   English

如何在 GraphQL-SPQR 中设置头变量

[英]How to set header variables in GraphQL-SPQR

I'm running a GraphQL API using GraphQL-SPQR and Spring Boot.我正在使用 GraphQL-SPQR 和 Spring Boot 运行 GraphQL API。

At the moment, I am throwing RuntimeException s to return GraphQL errors.目前,我正在抛出RuntimeException以返回 GraphQL 错误。 I have a customExceptionHandler that implements DataFetcherExceptionHandler that returns errors in the correct format, as shown below:我有一个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()
    }
}

I use the CustomExceptionHandler as follows (in my main application class):我使用CustomExceptionHandler如下(在我的主应用程序类中):

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

I'd like to set a header variable for a UUID that corresponds to the exception, for logging purposes.我想为与异常对应的 UUID 设置标头变量,以用于记录目的。 How would I do that?我该怎么做?

Even better, is it possible to create a Spring Bean that puts the UUID in the header for all queries and mutations?更好的是,是否可以创建一个 Spring Bean,将 UUID 放在所有查询和更改的标头中?

Thanks!谢谢!

when you're using spring boot, there's two options:当您使用 spring boot 时,有两种选择:

  • you're using the spring boot graphql spqr starter (which brings it's own controller to handle all graphQL requests)您正在使用 spring boot graphql spqr starter(它带有自己的控制器来处理所有 graphQL 请求)
  • you're using plain graphql-spqr and have your own controller to handle GraphQL requests您正在使用普通的 graphql-spqr 并拥有自己的控制器来处理 GraphQL 请求

In any case, you've got a few options:无论如何,您有几个选择:

Making your CustomExceptionHandler a Spring Bean and Autowiring HttpServletResponse使您的 CustomExceptionHandler 成为 Spring Bean 并自动装配 HttpServletResponse

That would probably be the easiest way to go - and it would probably work in any case: You could simply make your CustomExceptionHandler a Spring bean and have it autowire the HttpServletRequest - in the handler method, you could then set it to whatever you would like it to be.这可能是最简单的方法 - 它可能在任何情况下都可以工作:您可以简单地将 CustomExceptionHandler 设置为 Spring bean 并让它自动装配 HttpServletRequest - 在处理程序方法中,您可以将其设置为您想要的任何内容它是。 Here's some dummy code in Java (sorry, I am not proficient enough in Kotlin):这是 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
    }
}

This is going to work because spring will realise that HttpServletRequest differs for each request.这将起作用,因为 spring 将意识到 HttpServletRequest 因每个请求而异。 It will therefore inject a dynamic proxy into your error handler that will point to the actual HttpServletResponse instance for every request.因此,它将在您的错误处理程序中注入一个动态代理,该代理将指向每个请求的实际 HttpServletResponse 实例。

I would argue, that it's not the most elegant way, but it will certainly solve your problem.我会争辩说,这不是最优雅的方式,但它肯定会解决您的问题。

for the graphql-spqr spring boot starter用于 graphql-spqr spring boot starter

There's a default controller implementation that is used in projects using this starter.使用此启动器的项目中使用了默认控制器实现 That controller will handle every graphql request that you receive.该控制器将处理您收到的每个 graphql 请求。 You can customise it, by implementing your own GraphQLExecutor and making it a spring bean.您可以通过实现自己的GraphQLExecutor并使其成为 spring bean 来自定义它。 That executor is responsible to call the GraphQL engine, pass the parameters in and output the response.该执行器负责调用 GraphQL 引擎,传入参数并输出响应。 Here's the default implementation , that you might want to base your work on.这是默认实现,您可能希望以此为基础进行工作。

Similarly to the previous solution, you could autowire the HttpServletResponse in that class and set a HTTP Response header.与之前的解决方案类似,您可以在该类中自动装配 HttpServletResponse 并设置 HTTP 响应标头。

That solution would allow you to decide, if you want to set a request id in all cases, or just in specific error cases.该解决方案将允许您决定是要在所有情况下设置请求 ID,还是仅在特定错误情况下设置请求 ID。 ( graphql.execute returns an object from which you can get the information if and what errors existed) graphql.execute返回一个对象,您可以从中获取信息是否存在错误以及存在哪些错误)

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

Locate your GraphQL controller, add an argument to that method of type HttpServletRequest - and then add headers to that as you prefer (see previous section on some more specific suggestions)找到您的 GraphQL 控制器,向 HttpServletRequest 类型的该方法添加一个参数 - 然后根据您的喜好向该方法添加标头(有关更具体的建议,请参阅上一节)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM