【问题标题】:Graphql: completely change field type in schemaGraphql:完全改变模式中的字段类型
【发布时间】:2018-12-04 10:27:24
【问题描述】:

我需要彻底改变字段类型。

情况:我有一个结合了多种服务的网关。它通过自省来获取它们的模式,通过向类型添加命名空间(使用 apollo graphql-tools)并通过使用ServiceNameQuery 类型构建新模式并设置delegate 解析器将它们放入嵌套查询(例如Query: { ServiceName: { serviceQuery } })来转换它们。之后我需要创建跨服务链接。

我有一个ServiceA,它的类型具有属性related,其中包含来自TargetType 的ID 来自ServiceB。我需要将related 的属性类型从ID 更改为TargetType 并添加一个解析器,它将从ServiceB 获取数据。

这是一个真实的例子:

为此,我在合并架构上运行 visitSchema(来自 graphql-tools 转换),找到我需要的字段,从架构中获取 TargetType 并更改字段类型并设置如下解析器:

const targetType = schema.getType('TargetType');
field.type = targetType;
field.astNode.type = targetType.astNode;
field.resolve = (parent, args, ctx, info) => {
    console.log(parent);
    return null;
  };

当我在将结果模式传递给 graphql 服务器之前运行 console.log 类型时 - 我看到它的类型和 astNode 确实发生了变化并且它们是正确的。

当我运行自省时——我发现这种类型的字段是正确的。

但是当我运行像 query { ServiceA { serviceQuery { id related { id } } } } 这样的查询时,我在请求解析阶段遇到错误:

Error: Field "related" must not have a selection since type "ID" has no subfields.

GraphQL request (5:19)
4:       id
5:       related {
                     ^
6:         id

    at asErrorInstance (/.../node_modules/graphql/execution/execute.js:555:43)
    at process._tickCallback (internal/process/next_tick.js:68:7)

It 事件不会尝试调用 serviceQuery 解析器。

当我更改类型定义时,它从哪里获取该字段的 ID 类型?我还需要在哪里更改它的类型?

UPD 即使我这样创建新类型:

schema = return visitSchema(schema, {
    [VisitSchemaKind.OBJECT_TYPE](type: GraphQLObjectType) {
      if (type.getFields().relatedNews) {
        // console.log(type.getFields());
        return new GraphQLObjectType({
          name: type.name,
          fields: {
            ...fromPairs(Object.values(type.getFields()).map(({name, type, args, resolve, description}) => [name, {type, args: {}, resolve, description}])),
            relatedNews: {
              type: schema.getType('NewsArticle'),
              resolve(obj) {
                console.log('foo');
              }
            }
          }
        });
      }
      return type;
    },
  });

我不断收到此错误,但未触发解析程序。如果我以相同的方式添加一个具有不同名称的新字段 - 就可以了。但是如果名字相同——错误

【问题讨论】:

    标签: graphql apollo graphql-js apollo-server graphql-tools


    【解决方案1】:

    好的,我想通了。缝合模式跟踪底层缝合模式。在顶级架构中更改类型不会影响它,因此会导致内部类型冲突。所以类型应该在合并之前改变

    【讨论】:

    • 怎么样?可以举个例子吗?
    猜你喜欢
    • 2019-07-07
    • 2021-06-14
    • 2020-02-24
    • 2023-01-09
    • 2017-12-13
    • 2018-08-15
    • 2021-06-27
    • 2023-03-20
    • 2021-11-16
    相关资源
    最近更新 更多