【问题标题】:nestJs + gql route conflict/overridenestJs + gql 路由冲突/覆盖
【发布时间】:2021-09-21 10:14:37
【问题描述】:

大家好,我在我的 nestJS 应用程序中遇到了冲突/覆盖问题。

那么问题是什么:

我有解析器 A

@Resolver('ResolverA')
export class SomePageResolver {
  constructor(private readonly someService: someService) {
  }

  @Query(() => someType)
  theThingThatMessesUpStuff(
    @Args('params') params: HttpParamsInput,
    @Context(TokenPipe) authorization: string,
    ): Observable<ActionSetsPageType> {
    return this.someService.doSomething(params, authorization)
  }
}

还有一个解析器 B

@Resolver('ResolverB')
export class SomePageResolver{
  constructor(private readonly someService: someService) {
  }

  @Query(() => someOtherType)
  theThingThatMessesUpStuff(
    @Args('params') params: HttpParamsInput,
    @Context(TokenPipe) authorization: string,
    ): Observable<ActionSetsPageType> {
    return this.someService.doSomethingElse(params, authorization)
  }
}

Resolver A 分别是 Module A 的一部分,Resolver BModule B 的一部分。

根据我的构建,Module AModule B 有可能被导入到单个模块(单个父模块)中,这会导致覆盖问题。 问题的本质是,当两个模块都是构建的一部分时,如果客户端查询theThingThatMessesUpStuff,它将使用最后导入的模块进行查询

// some code
@Module({
  imports: [
    // some imports
    ModuleB,
    ModuleA
  ]
})
// some more code

如果使用上面的示例配置,每当客户端尝试查询 theThingThatMessesUpStuff 字段时,查询将由 ModuleA 内部的实现解决,其中一些功能(在与此相关的前端内部构建)客户端将期望在ModuleB中实现

现在回到主要问题,有没有一种方法可以在不涉及太多人的情况下创建一个验证,以保证在 nestJS 应用程序范围内只存在唯一的 GQL 查询。

【问题讨论】:

    标签: javascript typescript nestjs gql


    【解决方案1】:

    到目前为止,我已经想出了两个解决方案:

    1. 以某种方式在项目的所有团队和人员中实施命名约定,以某种前缀的形式,只要每个团队成员都知道并保持警惕,这将起到作用。

    2. 创建装饰器函数并装饰所有查询

    const registered = {};
    
    export const uniqueKey = () => {
      return function(_target: any, propertyKey: string) {
        if (registered[propertyKey]) {
          console.error(`${propertyKey} already in used`);
          throw new Error(`Resolver name already in use`);
        } else {
          registered[propertyKey] = true;
        }
      };
    };
    
    

    而这东西就照这样使用

    @Resolver('ResolverA')
    export class SomePageResolver {
      constructor(private readonly someService: someService) {
      }
    
      @uniqueKey()
      @Query(() => someType)
      theThingThatMessesUpStuff(
        @Args('params') params: HttpParamsInput,
        @Context(TokenPipe) authorization: string,
        ): Observable<ActionSetsPageType> {
        return this.someService.doSomething(params, authorization)
      }
    }
    
    

    再次使用这个解决方案,开发人员应该保持警惕并在任何地方使用装饰器,而且这个装饰器应该在整个代码库中应用,以保持一致性(这是非常不愉快的任务)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-15
      • 2018-03-25
      • 2018-06-07
      • 2018-05-23
      相关资源
      最近更新 更多