Nest-Fastify GraphQL设置Authorization Header遇response.header非函数错误
问题原因
你遇到的response.header is not a function错误,核心是Fastify响应对象(FastifyReply)的API版本适配问题,或是误用了异步调用方式。
解决方案
方案1:适配Fastify版本调整API
- Fastify v3及以下版本:该版本中设置响应头的方法是
setHeader,而非header。修改Resolver代码如下:
@Mutation((returns) => AccessToken, { nullable: true }) async registerUser( @Args('createUser') createUserInput: CreateUserInput, @Res({ passthrough: true }) response: FastifyReply, ): Promise<{ token: string }> { const token = await this.userService.registerUser(createUserInput); // 替换为setHeader方法 response.setHeader('Authorization', 'Bearer ' + token); return { token: token }; }
- Fastify v4及以上版本:该版本提供了
header方法,但它是同步方法,不需要加await。修改代码去掉await即可:
@Mutation((returns) => AccessToken, { nullable: true }) async registerUser( @Args('createUser') createUserInput: CreateUserInput, @Res({ passthrough: true }) response: FastifyReply, ): Promise<{ token: string }> { const token = await this.userService.registerUser(createUserInput); // 直接调用header方法,无需await response.header('Authorization', 'Bearer ' + token); return { token: token }; }
方案2:使用NestJS拦截器统一处理响应头(推荐)
如果需要在多个GraphQL操作中设置响应头,用拦截器更优雅:
- 创建拦截器文件
response-header.interceptor.ts:
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; import { GqlExecutionContext } from '@nestjs/graphql'; @Injectable() export class ResponseHeaderInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { const ctx = GqlExecutionContext.create(context); const response = ctx.getContext().reply; return next.handle().pipe( tap((data) => { // 返回结果包含token时自动设置响应头 if (data?.token) { response.header('Authorization', `Bearer ${data.token}`); } }), ); } }
- 在Resolver上应用拦截器:
@UseInterceptors(ResponseHeaderInterceptor) @Mutation((returns) => AccessToken, { nullable: true }) async registerUser( @Args('createUser') createUserInput: CreateUserInput, ): Promise<{ token: string }> { const token = await this.userService.registerUser(createUserInput); return { token: token }; }
这种方式无需直接操作响应对象,更贴合NestJS的设计思想。
内容的提问来源于stack exchange,提问作者PovarCoda
相关产品推荐
相关产品推荐

