【问题标题】:Javascript circular dependency in GraphQL codeGraphQL 代码中的 Javascript 循环依赖
【发布时间】:2016-08-24 10:43:42
【问题描述】:

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

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

【问题讨论】:

  • 可能以不同的方式为您的类型建模。您能否提供更多有关您的数据库架构的详细信息?
  • 谢谢@AhmadFerdousBinAlam 我有点想知道如何解决这个问题,我实际上将所有三种类型的关系、人员和公司都“取消链接”,但创建了另一个层,其中包含三个更复杂的版本关系”。
  • 我在自己的项目中遇到过这个问题。答案是为 GraphQL 使用 Interfacesgraphql.org/docs/api-reference-type-system/…

标签: javascript circular-dependency graphql


【解决方案1】:

尝试将您的 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.

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

【讨论】:

    【解决方案2】:

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

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

    这将为您提供两种类型之间的多对多关系,这听起来像是在您的数据库中定义的。

    这种风格的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 类型上看到这一点,例如 GraphQLInterfaceTypeGraphQLUnionType

    Star Wars example 帮助我解决了这些问题。

    【讨论】:

      猜你喜欢
      • 2017-07-20
      • 2016-11-09
      • 1970-01-01
      • 2020-10-27
      • 1970-01-01
      • 2022-12-07
      • 1970-01-01
      • 2017-05-24
      • 1970-01-01
      相关资源
      最近更新 更多