node.js - 如何实现 isTypeOf 方法?

标签 node.js typescript express graphql express-graphql

鉴于此模式:

interface INode {
  id: ID
}

type Todo implements INode {
  id: ID
  title: String!
}

type Query {
  node(id: ID!): INode
}

给定这个类:

export default class Todo {
  constructor (public id: string, public title: string) { }

  isTypeOf(value: any): Boolean {
    return value instanceof Todo;
  }
}

鉴于此解析器:

type NodeArgs = {
  id: string
}
export const resolver = {
  node: ({ id }: NodeArgs) => {
    return new Todo('1', 'Todo 1');
  }
}

当我调用查询时:

query {
  node(id: "1") {
    id
    ... on Todo {
      title
    }
  }
}

然后我得到下面的返回:

{
  "errors": [
    {
      "message": "Abstract type INode must resolve to an Object type at runtime for field Query.node with value { id: \"1\", title: \"Todo 1\" }, received \"undefined\". Either the INode type should provide a \"resolveType\" function or each possible type should provide an \"isTypeOf\" function.",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "node"
      ]
    }
  ],
  "data": {
    "node": null
  }
}

如您所见,我已经实现了 isTypeOf 函数,但我仍然收到错误消息。

我做错了什么?

注意事项:

  • 我正在使用 Typescript、express 和 express-graphql;

最佳答案

isTypeOf是以编程方式创建模式时传递给 GraphQLObjectType 的构造函数的函数。同上 resolveType函数和联合/接口(interface)。如果您使用 SDL 并使用 buildSchema 创建架构,没有办法将这些函数注入(inject)到您创建的模式中,就像您没有办法为 Query 以外类型的字段提供解析器一样。和 Mutation .

您有几个选择。一种选择是使用默认值 resolveType行为。这将检查 __typename对象上的属性,然后回退到调用 isTypeOf在每个实现类型上,直到它匹配。这意味着如果您正在使用一个类,那么执行如下操作就足够了:

export default class Todo {
  get __typename() {
    return 'Todo'
  }
}

更好的选择是删除 buildSchema并使用 makeExecutableSchema来自 graphql-tools .然后你可以定义你的 resolveType和/或 isTypeOf直接在您的解析器中运行。例如:

const resolvers = {
  Query: {
    node: (obj, args, context, info) => {
      return new Todo('1', 'Todo 1')
    }
  },
  INode: {
    __resolveType: (obj, context, info) => {
      if (obj instanceof Todo) return 'Todo'
    },
  }
}

您不仅可以轻松定义isTypeOfresolveType这样,您还可以轻松地为任何类型的字段添加解析器,并轻松添加自定义标量。如果您只使用 buildSchema,则无法(轻松)执行任何操作.

编辑:

如果您更喜欢使用 isTypeOf而不是 resolveType ,解析器看起来像这样:

const resolvers = {
  Query: {
    node: (obj, args, context, info) => {
      return new Todo('1', 'Todo 1')
    }
  },
  Todo: {
    __isTypeOf: (obj, context, info) => {
      return obj instanceof Todo
    },
  }
}

只有一个是必要的。要么写一个resolveType您使用的每个抽象类型的函数,写一个isTypeOf对于每个可以是抽象类型的对象类型。

关于node.js - 如何实现 isTypeOf 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53078554/

相关文章:

reactjs - 在构造函数或声明中初始化变量

javascript - 如何避免 TypeScript 中的虚假 'unused parameter' 警告

javascript - 本地模块node.js :can't load files other than index. js

node.js - Azure 上的 Express App 无法加载静态文件,状态 500

node.js - 在全局对象上声明的函数

node.js - 使用 Node.js 检查带有 Stripe 的信用卡重复项

node.js - 在 Node.JS 中使用 Passport 注册(注册)

javascript - 使用动态 URL 查询参数提供静态目录

node.js - Ubuntu 中 Node.js 中的 REST API 与 Express、MongoDB 和 Mongoose。第一次连接时出现 MongoError : failed to connect to server [127. 0.0.1:27017]

javascript - 测试 package.json types 属性是否适用于相应的 javascript 文件