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 
    }, 
    }, 
}); 
+0

以不同的方式建模您的类型也许是可能的。你能否提供关于数据库模式如何的更多细节? –

+0

谢谢@AhmadFerdousBinAlam我想到了如何解决这个问题,实际上我把所有三种类型的关系,人员和公司都'取消关联',但是在'关系'中创建了另一个更复杂版本的三层。 – Yechen

+0

我在自己的项目中遇到过这个问题。答案是为GraphQL使用'Interfaces'。 http://graphql.org/docs/api-reference-type-system/#graphqlinterfacetype – Chris

通常情况下,您不会定义特殊的关系类型。在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类型上,如GraphQLInterfaceTypeGraphQLUnionType

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.

注:如果一个人可以在一个公司一次只能工作,架构要简单得多。