GraphQL代码中的Javascript循环依赖关系
我是Javascript新手,不知道如何解决此问题。我创建一个GraphQL服务提供查询的数据库,我想定义三种类型:个人,公司和关系GraphQL代码中的Javascript循环依赖关系
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
},
},
});
通常情况下,您不会定义特殊的关系类型。在GraphQL中,类型之间的关系是在类型本身中定义的。
作为示例,在您的personType
中,您可以拥有一个名为companies
的字段,该字段可解析为该人员所属的公司列表(companyType
)。在您的companyType
中,您可以类似地定义将解析为personType
s列表的字段people
。
这会给你两种类型之间的多对多关系,它听起来像是在数据库中定义的。
一个personType
这种风格可能看起来像:
personType = new GraphQLObjectType ({
name: 'Person',
fields:() => ({
id: {
type: new GraphQLNonNull(GraphQLInt),
},
companies: {
type: new GraphQLList(companyType),
resolve: person => dbHandler.getAssociatedCompanies(person.id),
},
},
}),
});
至于循环依赖问题,上面的通知,而不是使用对象字面fields
,您可以改用返回该对象的功能,不会导致任何问题(尽管你的棉绒可能会抱怨)。
我肯定会建议您通读GraphQL Types,并确保您已选择适合您的字段的类型。一旦你足够舒适,你一定会想要调查GraphQLInterfaceType
,它允许你定义其他类型可以实现的通用字段。最终,它可能是一种更好的途径来分别定义你的类型,让他们实现一个接口,而不是通用的objectType
。
另请注意,resolveType
可能不会做你认为它的作用。从GraphQL类型:“[resolveType是一个函数,用于确定字段解析时实际使用哪种类型。”您会看到,在可以由多种类型组成的GraphQL类型上,如GraphQLInterfaceType
和GraphQLUnionType
。
Star Wars example帮我把这些东西包裹起来。
尝试调整你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.
注:如果一个人可以在一个公司一次只能工作,架构要简单得多。
以不同的方式建模您的类型也许是可能的。你能否提供关于数据库模式如何的更多细节? –
谢谢@AhmadFerdousBinAlam我想到了如何解决这个问题,实际上我把所有三种类型的关系,人员和公司都'取消关联',但是在'关系'中创建了另一个更复杂版本的三层。 – Yechen
我在自己的项目中遇到过这个问题。答案是为GraphQL使用'Interfaces'。 http://graphql.org/docs/api-reference-type-system/#graphqlinterfacetype – Chris