我是Javascript的新手,并且不知道如何解决这个问题。我正在创建一个GraphQL服务来为数据库提供查询,我想定义三种类型:Person,Company和Relationship
type Relation: {
person: Person
company: Company
}
type Person: {
relationship: Relation
}
type Company: {
relationship: Relation
}
正如你所看到的,它们是相互依赖的,我会得到人和公司undefined
,有没有办法解决这个问题?
数据库架构:
// -------------------- Object(company) --------------------
objectType = new GraphQLObjectType ({
name: 'Object',
description: 'Object could be a Company, FinancialOrg, Person or Product.',
fields: {
id: {
type: new GraphQLNonNull(GraphQLString),
},
entity_type: {
type: new GraphQLNonNull(GraphQLString),
description: 'could be Company, FinancialOrg, Person or Product.'
},
entity_id: {
type: new GraphQLNonNull(GraphQLInt),
},
parent_id: {
type: GraphQLString,
},
name: {
type: new GraphQLNonNull(GraphQLString),
},
normalized_name: {
type: new GraphQLNonNull(GraphQLString),
},
permalink: {
type: new GraphQLNonNull(GraphQLString),
}
},
resolveType: function(object) {
return dbHandler.findObjectById(object.id);
}
})
// -------------------- Relationship --------------------
var relationshipType = new GraphQLObjectType({
name: 'Relationship',
description: 'Describe the relationship between a person and a object(Corporation, fund)',
fields: {
id: {
type: new GraphQLNonNull(GraphQLInt),
},
relationship_id: {
type: new GraphQLNonNull(GraphQLInt),
},
person_object_id: {
type: new GraphQLNonNull(GraphQLString),
},
relationship_object_id: {
type: new GraphQLNonNull(GraphQLString),
description: 'A Corporation or a Fund',
},
}
});
// -------------------- Person Type --------------------
personType = new GraphQLObjectType ({
name: 'Person',
fields: {
id: {
type: new GraphQLNonNull(GraphQLInt),
},
object_id: {
type: new GraphQLNonNull(GraphQLString),
},
first_name: {
type: new GraphQLNonNull(GraphQLString),
},
last_name: {
type: new GraphQLNonNull(GraphQLString),
},
birthplace: {
type: GraphQLString
},
affiliation_name: {
type: GraphQLString
},
},
});
答案 0 :(得分:3)
通常,您不会定义特殊的关系类型。在GraphQL中,类型之间的关系在类型本身中定义。
例如,在您的personType
中,您可以拥有一个名为companies
的字段,该字段可解析为该人所属的公司列表(companyType
)。在companyType
中,您可以类似地定义要解析为people
列表的字段personType
。
这将基本上为您提供这两种类型之间的多对多关系,这听起来像是在数据库中定义的。
此样式中的personType
可能如下所示:
personType = new GraphQLObjectType ({
name: 'Person',
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLInt),
},
companies: {
type: new GraphQLList(companyType),
resolve: person => dbHandler.getAssociatedCompanies(person.id),
},
},
}),
});
至于循环依赖问题,请注意上面的内容,而不是使用fields
的对象文字,而是使用一个返回对象的函数,这不会导致任何问题(虽然你的linter可能会抱怨)。
我肯定会建议您阅读GraphQL Types,并确保为您的字段选择了合适的类型。一旦你足够舒服,你肯定想要调查GraphQLInterfaceType
,这允许你定义其他类型可以实现的公共字段。最终,它可能是分别定义类型并让它们实现接口而不是通用objectType
的更好途径。
另请注意,resolveType
可能无法完成您的想法。从GraphQL类型:" [resolveType is]一个函数,用于确定在解析字段时实际使用的类型。"您可以看到可以由多种类型组成的GraphQL类型,例如GraphQLInterfaceType
和GraphQLUnionType
。
Star Wars example帮助我绕过这些东西。
答案 1 :(得分:0)
尝试将GraphQL端点重构为此类
type Person: {
employers: [Company],
...personAttributes
}
type Company: {
employees: [Person],
...companyAttributes
}
在数据库架构中(我猜您正在使用关系数据库),您需要3个表:
This article explains how to model many-to-many relationships like the one you have.
注意:如果一个人一次只能在一家公司工作,那么架构就会简单得多。