[英]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 时,有两种选择:
In any case, you've got a few options:无论如何,您有几个选择:
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.我会争辩说,这不是最优雅的方式,但它肯定会解决您的问题。
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
返回一个对象,您可以从中获取信息是否存在错误以及存在哪些错误)
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.