首页 文章

Graphql:完全更改模式中的字段类型

提问于
浏览
2

我需要完全改变字段类型 .

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

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

这是一个现实生活中的例子:
enter image description here

为此,我在合并模式上运行 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;
  };

当我运行console.log时,在将结果模式传递给graphql server之前输入模式 - 我看到它的类型和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)

它事件不会尝试调用 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;
    },
  });

我一直收到此错误并且未触发解析器 . 如果我以相同的方式添加一个具有不同名称的新字段 - 这是有效的 . 但如果名称相同 - 错误

1 回答

  • 0

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

相关问题