You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeORM同一Resolver内如何调用需context参数的其他Mutation

TypeORM Resolver 跨Mutation调用解决方案

直接调用的实现方式

你要调用的addNote方法的第一个参数是框架注入的Context对象,你在updateNote中已经通过@Ctx()装饰器拿到了该对象,手动传入即可,修改后的代码如下:

@Mutation()
async updateNote(
    @Ctx() { req }: Context,
    @Arg('text', _type => string, { nullable: true }) text: string
    @Arg('noteId', _type => Int, { nullable: true }) noteId: Int    
  ) {
  // ...原有逻辑
  if (noteDoesNotExist) {
    // 手动构造addNote需要的context参数传入即可
    return this.addNote({ req }, text)
  }
  // ...原有逻辑
}

跨Mutation调用的合理性说明

这种做法不属于完全禁用的范畴,但不是最佳实践,存在以下明显缺陷:

  • 装饰器逻辑失效:只有框架触发的Mutation调用才会执行@Mutation相关的拦截逻辑(比如参数校验、权限校验、日志埋点等),手动调用属于普通函数调用,不会触发这些逻辑,容易出现隐式漏洞。
  • 复用层级不合理:Mutation属于接口层入口,仅负责处理外部请求的参数解析、上下文转换,核心业务逻辑应该下沉到Service层,复用逻辑应该在Service层完成,而非接口层。
  • 事务管理困难:跨Mutation调用很难统一管控事务,如果新增和修改操作需要在同一事务内执行,这种写法无法实现。

长期优化方案

建议将核心业务逻辑抽离到独立的Service层,两个Mutation都调用Service层的方法实现复用,示例如下:

// 业务逻辑层
@Injectable()
export class NoteService {
  constructor(private readonly noteRepository: Repository<Note>) {}

  async add(userId: number, text: string) {
    const note = this.noteRepository.create({ userId, text })
    return this.noteRepository.save(note)
  }

  async upsert(userId: number, noteId: number, text: string) {
    const note = await this.noteRepository.findOneBy({ id: noteId, userId })
    if (!note) {
      return this.add(userId, text)
    }
    note.text = text
    return this.noteRepository.save(note)
  }
}

// 接口层
@Resolver()
export class NoteResolver {
  constructor(private readonly noteService: NoteService) {}

  @Mutation()
  async addNote(
    @Ctx() { req }: Context,
    @Arg('text', _type => string, { nullable: true }) text: string
  ) {
    const userId = req.user.id
    return this.noteService.add(userId, text)
  }

  @Mutation()
  async updateNote(
    @Ctx() { req }: Context,
    @Arg('text', _type => string, { nullable: true }) text: string
    @Arg('noteId', _type => Int, { nullable: true }) noteId: Int    
  ) {
    const userId = req.user.id
    return this.noteService.upsert(userId, noteId, text)
  }
}

这种写法结构更清晰,后续修改业务逻辑仅需调整Service层代码,也能方便的接入事务、统一校验等能力。


内容的提问来源于stack exchange,提问作者HigoChumbo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 13:54:04