联邦图 | Federation

Apollo Federation 让您可以声明性地将多个 GraphQL API 组合成一个单一的联合图。这种联合图使客户端能够通过单个请求与多个 API 进行交互。

GQLoom Federation 提供了 GQLoom 对 Apollo Federation 的支持。

安装

npm
yarn
pnpm
bun
npm install graphql @gqloom/core @apollo/subgraph @gqloom/federation

GraphQL 指令

Apollo Federation Directives 用于描述如何将多个 GraphQL API 组合成一个联合图。

在 GQLoom 中,我们可以在对象和字段的 extensions 属性中的 directives 字段来声明 GraphQL 指令:

valibot
zod
graphql.js
import * as v from "valibot" import { asObjectType } from "../src" export const User = v.pipe( v.object({ id: v.string(), name: v.string(), }), asObjectType({ name: "User", extensions: { directives: { key: { fields: "id", resolvable: true } }, }, }) ) export interface IUser extends v.InferOutput<typeof User> {}

以上示例中,我们声明了一个 @key 指令,该指令将 User 对象的 id 字段标记为可解析字段,我们将得到如下的 Schema:

type User @key(fields: "id", resolvable: true) { id: String! name: String! }

我们有两种声明指令的格式:

  • 使用数组:
{ directives: [ { name: "validation", args: { regex: "/abc+/" } }, { name: "required", args: {}, } ] }
  • 使用键值对:
{ directives: { validation: { regex: "/abc+/" }, required: {} } }

解析引用 | Resolve Reference

@gqloom/apollo 提供了 resolveReference 函数来帮助您解析引用。

import { loom } from "@gqloom/core" import { resolveReference } from "@gqloom/federation" const { resolver, query } = loom export const UserResolver = resolver.of( User, { user: query(User, () => ({ id: "1", name: "John" })), }, { extensions: { ...resolveReference<IUser, "id">((user) => getUserByID(user.id)), }, } )

编织

@gqloom/federation 引入的 FederatedSchemaWeaver.weave 函数用于编织 Federation Schema。与 @gqloom/core 相比,@gqloom/apollo 中的 FederatedSchemaWeaver.weave 函数将输出携带指令(Directives)的 Schema。

另外值得注意的是,我们需要使用从 @apollo/subgraph 引入的 printSubgraphSchema 函数将 Schema 转换为文本格式以保留指令(Directives)。

import { FederatedSchemaWeaver } from "@gqloom/federation" import { printSubgraphSchema } from "@apollo/subgraph" const schema = FederatedSchemaWeaver.weave(UserResolver) const schemaText = printSubgraphSchema(schema)