apollo federationのためのschemaファイルをroverで用意する

はじめに

つい最近、apollo federation で複数のバックエンドの graphql を統合対応したのですが、schema の統合 ( supergraph の生成 ) に苦労したので備忘録しておきます。

apollo 公式の手順をちゃんと理解・実践すれば問題ない話です emoji-sweat_drops

何に困ったのか?

graphql code generator で schema を管理しているのですが、どうも apollo federation 用の schema を作成できませんでした。

Schema AST プラグインで schema を統合出力した際に、federation もうまく設定できないかと試したのですが、schema 自体は作れるのですが federation 対応ができませんでした。やり方を知っていたら教えてほしい… emoji-cry

# codegen.yml
# 各エンドポイントもしくはスキーマファイルを単純に結合したファイルができてしまう
dist/federation/schema.graphql:
  schema:
    # 同一のパッケージ内にあるローカルの schema ファイルを参照する
    - src/cms/**/*.graphql
    # 別エンドポイントの schema を参照する
    - http://localhost:52224/graphql
  plugins:
    - schema-ast

そこで、apollo 公式が用意している apollo rover cli で schema を素直に統合することで対応しました emoji-sweat

tl; dr

まずは、rover cli をインストール

npm i --save-dev @apollo/rover

# or

yarn add -D @apollo/rover

上述の codegen.yml を rover で schema を統合する設定ファイルに直すと以下になります。

# example.yml
# ローカルホストのポートは適当です
subgraphs:
  cms:
    routing_url: http://localhost:56000/graphql
    schema:
      file: dist/cms/schema.graphql
  ownself:
    schema:
      subgraph_url: http://localhost:52224/graphql
// schema出力用のコマンド例
{
  "scripts": {
    "build:federation": "rover supergraph compose --config rover.yml > schema.graphql"
  }
}

build すると 以下のような schema ファイルが出力され、各バックエンドのエンドポイントが組み込まれます。

# schema.graphql
・
・
enum join__Graph {
  CMS @join__graph(name: "cms", url: "http://localhost:56000/graphql")
  OWNSELF @join__graph(name: "ownself", url: "http://localhost:52224/graphql")
}

federation 用のバックエンドで以下のように読み込むことで、各バックエンドを叩けるようになります。

// exmaple.ts
const supergraphSdl = readFileSync("./schema.graphql").toString()

const gateway = new ApolloGateway({
  supergraphSdl,
})

設定ファイルについて

詳しくはこちら公式を参照ください。

  • cmsownself は、各 graphql エンドポイント ( subgraph ) の名前を任意に決めます
  • routing_url は、各 graphql エンドポイントを入力
  • schema.file は、ローカル内にある schema ファイルを指定

    • 単一の schema ファイルを指定する必要があるため、graphql code generator で統合出力された schema ファイルを参照するようにしています
    • graphql code generator で許される /**/*.graphql のようなワイルドカードができないため、複数ファイルを指定する必要がある場合は、何らか統合してあげる必要がありそうです emoji-sweat_drops
  • schema.subgraph_url は、introspection 用に指定するため不要な場合もあるのですが、未入力だとエラーになるため指定しています

おわりに

graphql code generator で federation に対応した schema を統合出力できないだろうか?

ちゃんと調べなさいですが、コントリビュートチャンスか!?と思ったり思わなかったり emoji-sweat_smile


Canji

クラウド周りをちょこまかしたい注意散漫人間。個人開発を楽しんでいたあの頃。