【问题标题】:Schema Stitching resolve conflict by adding prefixSchema Stitching 通过添加前缀解决冲突
【发布时间】:2019-07-02 06:59:49
【问题描述】:

所以我有这两个模式

架构1

type Permission {
    relation: Relation
}

enum Relation {
    ONE
    TWO
    THREE
}

架构2

type Permission {
    relation: Relation
}

enum Relation {
    FOUR
    FIVE
    SIX
}  

预期结果类似于:(但我对不同的想法持开放态度) 合并后我想做的查询是:

{
    permissions{
        relation
    }
}

得到类似的结果

"permissions": [
  {
    "relation": "ONE"
  },
  {
    "relation": "SIX"
  }
]

"permissions": [
  {
    "relation": "schema1ONE"
  },
  {
    "relation": "schema2SIX"
  }
]

还有像这样的突变:

mutation{
  createPermission(
    relation: ONE
  ){
    relation
  }
}

mutation{
  createPermission(
    relation: SIX
  ){
    relation
  }
}

mutation{
  createPermission(
    relation: schema1ONE
  ){
    relation
  }
}

mutation{
  createPermission(
    relation: schema2SIX
  ){
    relation
  }
}

我正在尝试在 graphql-tools 上使用 transformSchema 函数,但不能完全正确地弄清楚:

const Schema1 = await getRemoteSchema('schema1_url', 'schema1');
const Schema2 = await getRemoteSchema('schema2_url', 'schema2');

const schemas = [Schema1, Schema2]

const schema = mergeSchemas({
  schemas: schemas,
  resolvers: {}
});

getRemoteSchema 定义

export const getRemoteSchema = async (uri: string, schemaName: string): Promise<GraphQLSchema> => {
  const httpLink = new HttpLink({ uri, fetch });

  const schema = await introspectSchema(httpLink);

  const executableSchema = makeRemoteExecutableSchema({
    schema,
    httpLink,
  });

  // transform schema by renaming root fields and types
  const renamedSchema = transformSchema(
    executableSchema,
    [
      new RenameTypes(name => {
        if (name == 'Relation') {
          return schemaName + name
        } else {
          return name
        }
      }),
      // new RenameRootFields((operation, name) => `${schemaName}_${name}`)
    ]
  );

  return renamedSchema;
}    

我犯了这个错误https://glitch.com/edit/#!/schema-stitching-conflict 所以更容易看出问题。

【问题讨论】:

  • 所以一方面是类型的重命名,还有权限类型的加入

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


【解决方案1】:

您需要 RenameTypesRenameRootFields 转换, RenameTypes 转换类型名

来自:PermissionRelation(碰撞类型),

收件人:schema1_Permissionschema2_Permission

和:schema1_Relationschema1_Relation

RenameRootFields 为这些类型转换查询名称

来自:permission(id: ID!): Permission

收件人:schema1_permission(id: ID!): schema1_Permissionschema2_permission(id: ID!): schema2_Permission

和:permissions: [Permission]

收件人:schema1_permissions: [schema1_Permission]schema2_permissions: [schema2_Permission]

转换将类似于:

const {
  makeExecutableSchema,
  addMockFunctionsToSchema,
  transformSchema,
  RenameTypes,
  RenameRootFields
} = require('graphql-tools');

const schema1 = makeExecutableSchema({
  typeDefs: `
    type Permission {
      id: ID!
      text: String
      relation: Relation
    }

    type Query {
      permissions: [Permission]
      permission(id: ID!): Permission
    }

    enum Relation {
      ONE
      TWO
      THREE
    }
  `
});

addMockFunctionsToSchema({ schema: schema1 });

const renamedSchema1 = transformSchema(
  schema1,
  [
    new RenameTypes(name => {
      if (name == 'Relation' || name == 'Permission') {
        return 'schema1_' + name
      } else {
        return name
      }
    }, { renameBuiltins: false, renameScalars: true }),
    new RenameRootFields((_op, name) => {
      return name.includes('ermission') ? `schema1_${name}` : name
    })
  ]
);

参考: https://www.apollographql.com/docs/graphql-tools/schema-transforms/ https://www.apollographql.com/docs/graphql-tools/schema-stitching/

【讨论】:

    【解决方案2】:

    目前我看不到使用 graphql-tools 实现所需行为的简单方法,因为在mergeSchemas() 的实现中,选项onTypeConflictfirst deprecated and later removed,即使它仍然存在于公共接口上。使用该选项,我们能够简单地传递一个回调,该回调知道冲突类型及其对应的 AST。

    transformSchema() 但是,当您尝试使用它时,只会重命名枚举类型名称而不重命名枚举值。您很可能需要实现自己的转换,而不是使用预定义的转换来实现您的目标。不过,我想建议您看看the implementationConvertEnumValues。在实现自己的Transform 时,这可能会让您更好地了解如何根据需要行走和操作 AST。

    例如,我会考虑一个实现,它会跟踪它看到的所有GraphQlEnumTypes,并在遇到名称冲突时深度合并它们。您可以使用模块范围内的变量或使用Transform 中的实例属性来跟踪。如果你做后者,不要忘记提前实例化它并通过引用将它传递给后续的tranformSchema()调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-23
      • 2017-02-01
      • 2021-10-01
      • 2020-12-15
      • 2017-02-08
      • 2012-04-07
      • 2011-05-08
      • 1970-01-01
      相关资源
      最近更新 更多