【问题标题】:Can't figure out how to use Schema Directives when moving to Typescript迁移到 Typescript 时无法弄清楚如何使用模式指令
【发布时间】:2021-02-19 21:50:19
【问题描述】:

我花了几天时间将我的 GraphQL 服务器重写为 Typescript,但最终,我陷入了定义 Schema Directives 的困境。已经花了很多时间在谷歌上搜索,但没有找到使用 Typescript 的“更高级”的 Apollo GraphQL 示例。

当我使用纯 Javascript 时,它非常适合我,没有任何问题,我的指令看起来像这样:

// TS but no difference from JS in terms of extended class or method overriden
export default class UserAuthDirective extends SchemaDirectiveVisitor {
  visitFieldDefinition(field: any, details: any) {
    field._requiredRole = this.args.role
    const { resolve = defaultFieldResolver } = field
    field.resolve = function (...args: any) {
      // LOGIC CHECKING ROLES
    }
  }
}

我使用 graphql-tools 库中的 makeExecutableSchema,如下所示:

// Again basically identical with original JS
const schema = makeExecutableSchema({
  typeDefs: mergeTypes(types, { all: true }),
  resolvers: loadResolvers(),
  logger: {
    log: (e) => logger.error(e.message, e),
  },
  allowUndefinedInResolve: false,
  inheritResolversFromInterfaces: true,
  resolverValidationOptions: {
    allowResolversNotInSchema: false,
    requireResolversForResolveType: true,
  },
  schemaDirectives: {
    userHas: UserAuthDirective,
    // ^^^ Here I'm getting. "Type 'typeof UserAuthDirective' is not assignable to type 'typeof SchemaDirectiveVisitor'. Types of property 'visitSchemaDirectives' are incompatible."
  },
})

SchemaDirectiveVisitor 的构造函数受到保护,因此我无法从那里实例化该类。 我不是真正的高级 Typescript 用户,所以也许我只是完全错误地理解它或遗漏了一些基本概念,但我真的坚持这一点,并且很高兴有任何提示或猜测我可能做错了什么。

谢谢:-)

【问题讨论】:

  • 您是从graphql-toolsapollo-server 导入SchemaDirectiveVisitor 吗?
  • 伙计,你为我节省了很多拉头发 :-D 非常感谢!当然,我使用的是apollo-server 而不是graphql-tools

标签: javascript typescript apollo-server graphql-js


【解决方案1】:

您需要确保从正确的包中导入 SchemaDirectiveVisitor -- graphql-tools 而不是 apollo-server。根据每个包的版本,很可能每个包导出的SchemaDirectiveVisitor类不兼容。

【讨论】:

    【解决方案2】:

    我在您的 visitFieldDefinition 方法中看到两个参数。

    这个类的实现随着graphql的实现而变化。

    如果您使用的是 apollo-server

    在实现SchemaDirectiveVisitor 时,您需要重写其中一种访问方法,并且这些方法只接受一个参数。因此,该方法被重载而不是被覆盖。

    请参考以下页面:

    https://www.apollographql.com/docs/apollo-server/schema/creating-directives/

    如果您使用的是 graphql-tools

    该方法接受 2 个参数,看起来像 visitFieldDefinition(field: GraphQLField<any, any>, details: { objectType: GraphQLObjectType | GraphQLInterfaceType })

    请参考以下页面:

    https://www.graphql-tools.com/docs/legacy-schema-directives/#implementing-schema-directives

    【讨论】:

    • 这真的很奇怪,因为 SchemaDirectiveVisitor 实际上扩展了 SchemaVisitor,visitFieldDefinition 定义如下所示:typescript visitFieldDefinition(field: GraphQLField<any, any>, details: { objectType: GraphQLObjectType | GraphQLInterfaceType; }): GraphQLField<any, any> | void | null;
    • 在这种情况下,您需要弄清楚您使用的是哪个确切的实现。函数定义因实现而异,apollo-server 仅使用一个参数,graphql-tools 使用 2 个参数
    • 是的,你说得对,非常感谢@MegaMind。丹尼尔·里尔登一针见血——我使用了错误包中的 SchemaDirectiveVisitor。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多