加入我们,从10月8日至10日在纽约市,学习关于GraphQL Federation和API平台工程的最新技巧、趋势和新闻。参加2024年在纽约市的GraphQL峰会
文档
免费开始

在Apollo Federation中执行实体所有权

在Apollo Federation 2中指定实体所有权

联盟

Federation 2中,“扩展”一个类型的概念是严格的。所有不同中对类型的定义都根据的可共享性进行合并。在下面的示例中,没有任何子图真正拥有或扩展了Product实体。相反,它们都为其贡献了字段。

subgraph-a.graphql
type Product @key(fields: "id") {
id: ID!
name: String
}
subgraph-b.graphql
type Product @key(fields: "id") {
id: ID!
reviews: [Review]
}

联邦1要求其中一个定义使用了 extend 关键字或 @extends 。联邦2取消这项要求以提高 的灵活性并减少硬组合错误的可能。

然而,在某些情况下,您仍然可能想指定一个 实体 的 “所有者” 并使 “实体扩展” 成为 中的第一类概念。

一个例子是断言哪个 负责记录一个 实体。如果两个子图向一个类型添加不同的描述, 组合 选择其中一个描述并向您发出不一致的提示:

HINT: [INCONSISTENT_DESCRIPTION]: Element "Product" has inconsistent
descriptions across subgraphs. The supergraph will use description
(from subgraph "one"):
"""
The Product type lorem ipsum dolar sit amet.
"""
In subgraph "two", the description is:
"""
This is my description of the Product type.
"""

注意

当描述在 子图 中不一致时, 组合 将根据名称按字母顺序从第一个子图中选择描述。

决定类型的 “所有者” 的机制允许工具(如代码审查工具)在开发过程中较早捕获这些不一致。

创建 @owner 指令

您可以使用 Federation 2.2 中引入的 @composeDirective 功能将 @owner 指令添加到您的 supergraph

subgraph-a.graphql
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@key", "@composeDirective"])
@link(url: "https://graphql.mycompany.dev/owner/v1.0", import: ["@owner"])
@composeDirective(name: "@owner")
directive @owner(team: String!) on OBJECT
type Product @key(fields: "id") @owner(team: "subgraph-a") {
id: ID!
name: String
}

现在 @owner 指令出现在了 超图 中。因为我们没有将指令定义为 可重复的 子图 无法使用不同的 定义它。

使用 @owner 指令编写 lint 规则

以下是使用 @graphql-eslint 规则的例子,该规则用于 ,并且使用 @owner 指令来确定是否需要一个描述:

使用 @owner 确定所需审批者

对于 @owner 指令的另一个用例是在模式更改影响另一个团队拥有的类型时,确定所需的审查者。

具体过程取决于您的源代码控制和持续集成系统。以下示例步骤假设您同时使用 GitHub。

  1. 添加一个 pull_request 工作流程:

    .github/workflows/add-reviewers.yaml
    name: Add required reviewers for owned GraphQL types
    on: [pull_request]
  2. 确定方案更改影响的类型

    import { diff } from "@graphql-inspector/core";
    import { buildSchema } from "graphql";
    const differences = diff(
    buildSchema(schemaFromBaseRef, { assumeValidSDL: false }),
    buildSchema(schemaFromCurrentRef, { assumeValidSDL: false })
    );
    /* Derive a list of affected types from the result:
    [
    {
    "criticality": {
    "level": "NON_BREAKING"
    },
    "type": "FIELD_ADDED",
    "message": "Field 'newField' was added to object type 'Product'",
    "path": "Product.newField"
    }
    ]
    */
  3. 获取

    您可以使用 rover supergraph fetch 或使用 Apollo Platform API.

  4. 提取受影响类型的所有者

    import { getDirective } from "@graphql-tools/utils";
    const supergraphSchema = buildSchema(supergraphSdl);
    const affectedTeams = [];
    for (const typeName of affectedTypes) {
    const type = supergraphSchema.getType(typeName);
    const owner = getDirective(schema, type, "owner")?.[0];
    if (owner) {
    affectedTeams.push(owner.team);
    }
    }
  5. 将团队添加为拉取请求的审阅者

    import { Octokit } from "@octokit/action";
    const octokit = new Octokit();
    const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/");
    await octokit.pulls.requestReviewers({
    owner,
    repo,
    pull_number: pullNumber, // ${{ github.event.number }}
    team_reviewers: affectedTeams,
    });
下一步
首页
评分文章评分在 GitHub 上编辑编辑论坛Discord

©2024Apollo Graph Inc.,即 Apollo GraphQL。

隐私策略

公司