Apollo Graphql Schema Stitching Conflict

时间:2017-11-10 16:18:42

标签: javascript node.js graphql apollo

我有关于GraphQL Schema拼接的问题。 我有两个Graphql Schema:

type Name {
   firstname: String!
   lastname: String!
}

type Address {
   street: String!
   number: Int!
}

type User {
   name: Name!
   address: Address!
}

type Query {
   user(userId: String!): User
}

type User {
   age: String!
}

type Query {
   user(userId: String!): User
}

我现在尝试使用graphql-tools&{39} mergeSchemas函数合并模式:

const schema = mergeSchemas({
   schemas: [schema1, schema2]
});

但不是我想要实现的(扩展的用户类型):

type Name {
   firstname: String!
   lastname: String!
}

type Address {
   street: String!
   number: Int!
}

type User {
   name: Name!
   address: Address!
   age: String!
}

type Query {
   user(userId: String!): User
}

它导致了这个:     类型名称{        firstname:String!        姓氏:字符串!     }

type Address {
   street: String!
   number: Int!
}

type User {
   name: Name!
   address: Address!
}

type Query {
   user(userId: String!): User
}

最终架构中只显示一个UserTypes。 我尝试使用onTypeConflict中的mergeSchemas API来扩展类型,但我还没有取得任何结果。

有没有办法通过扩展冲突类型来合并架构?

2 个答案:

答案 0 :(得分:2)

这是合并对象类型的可能解决方案。也许在onTypeConflict中按类型名称进行过滤而不是合并每种类型都是有意义的。

import cloneDeep from 'lodash.clonedeep'
import { GraphQLObjectType } from 'graphql/type/definition'
import { mergeSchemas } from 'graphql-tools'

function mergeObjectTypes (leftType, rightType) {
  if (!rightType) {
    return leftType
  }
  if (leftType.constructor.name !== rightType.constructor.name) {
    throw new TypeError(`Cannot merge with different base type. this: ${leftType.constructor.name}, other: ${rightType.constructor.name}.`)
  }
  const mergedType = cloneDeep(leftType)
  mergedType.getFields() // Populate _fields
  for (const [key, value] of Object.entries(rightType.getFields())) {
    mergedType._fields[key] = value
  }
  if (leftType instanceof GraphQLObjectType) {
    mergedType._interfaces = Array.from(new Set(leftType.getInterfaces().concat(rightType.getInterfaces())))
  }
  return mergedType
}

const schema = mergeSchemas({
  schemas: [schema1, schema2],
  onTypeConflict: (leftType, rightType) => {
    if (leftType instanceof GraphQLObjectType) {
      return mergeObjectTypes(leftType, rightType)
    }
    return leftType
  }
})

致谢:mergeObjectTypes函数由Jared Wolinsky撰写。

答案 1 :(得分:2)

这应该有帮助

extend type User {
   age: String!
}