GraphQL代码中的Javascript循环依赖性 [英] Javascript circular dependency in GraphQL code

查看:59
本文介绍了GraphQL代码中的Javascript循环依赖性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Java语言的新手,不知道如何解决此问题。我正在创建一个GraphQL服务来提供对数据库的查询,我想定义三种类型:人员,公司和关系

I am new to Javascript and don't know how to solve this problem. I am creating a GraphQL service to provide query to a database, I would like to define three type: Person, Company and Relationship

type Relation: {
  person: Person
  company: Company
}

type Person: {
  relationship: Relation
}

type Company: {
  relationship: Relation
}

如您所见,它们是相互依赖的,我会给Person和Company 未定义,有没有办法解决这个问题?

As you can see, they are mutually depended, I will got Person and Company undefined, is there a way to resolve this?

数据库架构:

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


推荐答案

通常,您不会定义特殊的Relationship类型。在GraphQL中,类型之间的关系由类型本身定义。

Normally you wouldn't define a special Relationship type. In GraphQL, relationships among types are defined in the types themselves.

例如,在您的 personType 中,您可以有一个名为 companies 的字段,该字段解析为该人所属公司的列表( companyType s)。在您的 companyType 中,您可以类似地定义一个字段 people ,该字段将解析为的列表。 personType s。

As examples, within your personType, you can have a field called companies, which resolves to a list of companies (companyTypes) that person is part of. In your companyType, you could similarly define a field people that would resolve to a list of personTypes.

这实际上将为您提供两种类型之间的多对多关系,这听起来像是在您的定义中定义的

This would give you essentially a many-to-many relationship between the two types, which it sounds like is defined in your database.

A personType 可能看起来像这样:

A personType in this style might look like:

personType = new GraphQLObjectType ({
  name: 'Person',
  fields: () => ({
    id: {
      type: new GraphQLNonNull(GraphQLInt),
    },
    companies: {
      type: new GraphQLList(companyType),
      resolve: person => dbHandler.getAssociatedCompanies(person.id),
      },
    },
  }),
});

关于循环依赖问题,请注意,在上面不要将对象文字用于字段,您可以改用返回对象的函数,该函数不会引起任何问题(尽管您的短毛猫可能会抱怨)。

As for circular dependency issues, notice above that rather than using an object literal for fields, you can instead use a function which returns the object, which will not cause any problems (though your linter might complain).

我绝对建议您阅读 GraphQL类型,并确保您为您的字段选择了合适的类型。一旦感到足够舒适,您肯定会想要研究 GraphQLInterfaceType ,它可让您定义其他类型可以实现的常见字段。最终,这可能是更好的方法,分别定义类型并让它们实现接口,而不是具有通用的 objectType

I would definitely suggest reading through the GraphQL Types as well and making sure you've chosen appropriate types for your fields. Once you're comfortable enough you will definitely want to investigate GraphQLInterfaceType, which allows you to define common fields other types can implement. Ultimately it's probably a better route to define your types separately and have them implement an interface rather than having a generic objectType.

还要注意, resolveType 可能并没有按照您的想象做。从GraphQL类型中: [resolveType是]一个函数,用于确定在解析字段时实际使用的类型。您会看到在可以由多种类型组成的GraphQL类型上,例如 GraphQLInterfaceType GraphQLUnionType

Also note that resolveType probably doesn't do what you think it does. From the GraphQL Types: "[resolveType is] a function to determine which type is actually used when the field is resolved." You see that on GraphQL types that can be composed of multiple types, like GraphQLInterfaceType and GraphQLUnionType.

《星球大战》例子帮助我把这个想法弄清楚了。

The Star Wars example helped me wrap my head around this stuff.

这篇关于GraphQL代码中的Javascript循环依赖性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆