🗺️

Goで始めるGraphQL Federation

2023/07/25に公開

この抜粋の内容は次のとおりです。

  • Subgraph Server の実装
  • Gateway Server の実装
  • Subgraph を通す
  • Gateway を通す

さらに詳しく知りたい方は読み続けてください。


2023年7月4回目です。

GraphQL Fedetaion についてです。

弊社のモバイルアプリの1つは、ユーザーのネットワーク帯域幅による影響を避けるため、GraphQL を BFF(Backend For Frontend)[1] として使っています。

単一ドメイン業務においては、1つの GraghQL で問題ないと思います。
しかし、複数のドメイン業務を扱う場合、各チームは独立して自分たちの GraphQL サービスを開発するため、Supergraph(GraghQL Federation)[2] にしていく必要があると思います。

現在弊社の第1言語は、Go です。Go による GraphQL Federation について見ていきます。

Subgraph Server の実装

  • 構成
    • go version go1.20.5 linux/arm64
    • gqlgen

https://github.com/99designs/gqlgen

Subgraph[3] 用の GraphQL Server を立てます。

go install github.com/99designs/gqlgen@latest
gqlgen version
mkdir -p users/
cd users/
go mod init github.com/danny-yamamoto/go-graphql-federation-example/users
go get -u github.com/99designs/gqlgen
gqlgen init

Query[4] を仮実装します。

https://github.com/danny-yamamoto/go-graphql-federation-example/blob/0654159a1fb0455f0c81e0d15261e64fc57dc050/users/graph/schema.resolvers.go#L16-L25

https://github.com/danny-yamamoto/go-graphql-federation-example/blob/0654159a1fb0455f0c81e0d15261e64fc57dc050/users/graph/schema.resolvers.go#L43-L64

これで Subgraph 側の準備は完了です。

Gateway Server の実装

  • 構成
    • go version go1.20.5 linux/arm64
    • Bramble

Gateway として、Bramble を使います。

https://movio.github.io/bramble/#/

Bramble の設定に手こずりました。
Subgraph に通すには、config.json の定義と schema.resolvers.go の実装が必要です。

https://github.com/danny-yamamoto/go-graphql-federation-example/blob/main/cmd/bramble/config.json

Service を足します。

https://github.com/danny-yamamoto/go-graphql-federation-example/blob/7b025a8d1d62a6cfe1dabfee4086b6bcc4563140/users/graph/schema.graphqls#L18-L21

gqlgen generate

generate 後、Service の schema 処理を追記します。

https://github.com/danny-yamamoto/go-graphql-federation-example/blob/42da3f5ea68f78d614154b335fceba4e853b300b/users/graph/resolver.go#L9-L11

https://github.com/danny-yamamoto/go-graphql-federation-example/blob/42da3f5ea68f78d614154b335fceba4e853b300b/users/server.go#L22-L23

https://github.com/danny-yamamoto/go-graphql-federation-example/blob/42da3f5ea68f78d614154b335fceba4e853b300b/users/graph/schema.resolvers.go#L29-L40

これで、両方の実装が完了です。

Subgraph を通す

さっそく、Subgraph から確認します。

vscode ➜ /workspaces/go-graphql-federation-example/users (main) $ go run server.go 
2023/07/25 10:10:31 connect to http://localhost:4000/ for GraphQL playground

Playground で Query を実行します。

Gateway を通す

次に、Gateway から Subgraph まで通します。

root ➜ /workspaces/go-graphql-federation-example/cmd/bramble (main) $ go run main.go -conf ./config.json 
{"level":"info","msg":"service was updated","service":"user-service","time":"2023-07-27T11:04:18.772381503Z","version":"0.1.0"}
{"level":"info","msg":"service was updated","service":"user-service","time":"2023-07-27T11:04:18.774028711Z","version":"0.1.0"}
{"level":"info","msg":"rebuilding merged schema","time":"2023-07-27T11:04:18.774050753Z"}
{"level":"info","msg":"enabled plugins: []","time":"2023-07-27T11:04:18.77409117Z"}
{"config":{"id-field-name":"","gateway-address":"","disable-introspection":false,"metrics-address":"","private-address":"","gateway-port":8082,"metrics-port":9009,"private-port":8083,"services":["http://localhost:4000/query","http://localhost:4001/query"],"loglevel":"debug","poll-interval":"10s","PollIntervalDuration":10000000000,"max-requests-per-query":50,"max-service-response-size":1048576,"Plugins":null,"Extensions":null,"QueryHTTPClient":null},"level":"debug","msg":"configuration","time":"2023-07-27T11:04:18.774097795Z"}
{"addr":":8082","level":"info","msg":"serving public handler","time":"2023-07-27T11:04:18.774284503Z"}
{"addr":":9009","level":"info","msg":"serving metrics handler","time":"2023-07-27T11:04:18.774468086Z"}
{"addr":":8083","level":"info","msg":"serving private handler","time":"2023-07-27T11:04:18.774532461Z"}
vscode ➜ /workspaces/go-graphql-federation-example (main) $ curl -X POST -H "Content-Type: Application/json" -d '{"query":"{ todos { id text } }"}' http://localhost:8082/query
{"data":{"todos":[{"id":"TODO-1","text":"My Todo 1"},{"id":"TODO-2","text":"My Todo 2"}]}}
vscode ➜ /workspaces/go-graphql-federation-example (main) $ 
root ➜ /workspaces/go-graphql-federation-example/contact (main) $ curl -X POST -H "Content-Type: Application/json" -d '{"query":"{ contacts { firstname } }"}' http://localhost:8082/query
{"data":{"contacts":[{"firstname":"mirai"}]}}
root ➜ /workspaces/go-graphql-federation-example/contact (main) $ 

Summary

  • GraphQL Federation について書きました。
  • Gateway として、Bramble を使いました。
  • Gateway の起動は、最後である必要があります。deploy 時は、起動順番に気を使う必要があると思います。
脚注
  1. https://zenn.dev/overflow_offers/articles/20220418-what-is-bff-architecture ↩︎

  2. https://www.apollographql.com/supergraph/ ↩︎

  3. https://www.apollographql.com/docs/federation/v1/subgraphs/ ↩︎

  4. https://hasura.io/learn/ja/graphql/intro-graphql/graphql-queries/ ↩︎

Discussion