如何在graphql-java解析器中设置自定义响应头?
在Spring Boot GraphQL(Kotlin)中为响应添加自定义头
由于GraphQL Java(Spring Boot Starter GraphQL)不会处理解析器返回的ResponseEntity,因此需要采用以下两种可行方案实现自定义响应头的设置:
方法一:通过GraphQlInterceptor全局拦截设置头
该方案适合根据请求通用属性(如请求参数、用户上下文等)统一或动态设置响应头。
- 实现
WebGraphQlInterceptor接口:
import org.springframework.graphql.server.WebGraphQlInterceptor import org.springframework.graphql.server.WebGraphQlRequest import org.springframework.graphql.server.WebGraphQlResponse import reactor.core.publisher.Mono class CustomHeaderInterceptor : WebGraphQlInterceptor { override fun intercept(request: WebGraphQlRequest, chain: WebGraphQlInterceptor.Chain): Mono<WebGraphQlResponse> { return chain.next(request) .doOnNext { response -> // 从请求变量中获取参数,动态决定头内容 val arg1 = request.variables["arg1"]?.toString() val headerValue = when(arg1) { "value1" -> "header-for-value1" "value2" -> "header-for-value2" else -> "default-header-content" } // 通过ServerWebExchange设置HTTP响应头 request.serverWebExchange?.response?.headers?.add("X-My-Header", headerValue) } } }
- 将拦截器注册为Spring Bean:
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @Configuration class GraphQLConfig { @Bean fun customHeaderInterceptor(): CustomHeaderInterceptor { return CustomHeaderInterceptor() } }
方法二:解析器返回DataFetcherResult,结合拦截器提取头信息
如果需要由解析器自身决定响应头内容,可以让解析器返回DataFetcherResult,将头信息存入扩展字段,再通过拦截器提取并设置到响应中。
- 修改解析器返回
DataFetcherResult:
import org.springframework.graphql.data.method.annotation.Argument import org.springframework.graphql.data.method.annotation.QueryMapping import org.springframework.graphql.execution.DataFetcherResult @QueryMapping fun myResolver( @Argument arg1: String, @Argument arg2: MyInput, ): DataFetcherResult<MyEntity> { val entity = service.getMyEntity(arg1, arg2) // 将自定义头信息存入extensions val extensions = mapOf("X-My-Header" to when(arg1) { "special" -> "special-header-value" else -> "regular-header-value" }) return DataFetcherResult.newResult<MyEntity>() .data(entity) .extensions(extensions) .build() }
- 调整拦截器从扩展字段提取并设置头:
class CustomHeaderInterceptor : WebGraphQlInterceptor { override fun intercept(request: WebGraphQlRequest, chain: WebGraphQlInterceptor.Chain): Mono<WebGraphQlResponse> { return chain.next(request) .doOnNext { response -> val headerValue = response.extensions["X-My-Header"]?.toString() headerValue?.let { request.serverWebExchange?.response?.headers?.add("X-My-Header", it) } } } }
注意:两种方案均依赖ServerWebExchange,仅适用于HTTP传输场景;若使用WebSocket等其他传输方式,需调整对应逻辑。
内容的提问来源于stack exchange,提问作者Valentin Kuhn
相关产品推荐
相关产品推荐

