はじめに
取り組むApollo Tutorialを間違えてしまい、Apollo Connectorsを学んでしまいました。
間違えて終わりだと悲しいので記事を投稿することで供養とします。
本記事の内容
- Apollo Connectorsについて
- Apollo Connectorsを動かす
- RESTのエンドポイントを叩いてみる
Apollo Connectorsについて
Apollo Connectorsは、Apollo GraphOSの一機能として、既存のREST APIやGraphQL APIを簡単にGraphQLサブグラフとして統合できる仕組みです。
GraphQLを使いたいけど、既存のREST APIをすぐにGraphQLに置き換えるのは負担が大きい場合があります。Apollo Connectorsを活用することで、RESTのエンドポイントにそのままGraphQLでリクエストを送ることができる。
この仕組みによって、既存のAPIを活かしながら、段階的にGraphQLを導入することができます。
Apollo Connectorsを試すまで
以下ほぼ公式チュートリアルの内容なので、詳細を確認したい方は公式チュートリアルからどうぞ
Apollo GraphOSアカウントを用意
Roverのインストール
- Linux / Mac
$ curl -sSL https://rover.apollo.dev/nix/latest | sh
- Windows
$ iwr 'https://rover.apollo.dev/win/latest' | iex
API Keyを取得する
任意の名前をAPIにつけて発行する。
新規の組織の場合
既存のGraphがある場合
Personal Setting > API Keys > Create API Key
roverを認証する
先ほどのAPI Keyを使って以下を実行する。
rover config auth
の後にAPI Keyの入力を求められる。
$ rover config auth
$ rover config whoami
プロジェクトを作る
作業ディレクトリ下で以下のコマンドを実行。
$ rover init
すると、いくつか質問がされます。
- Select option
- Create a new graph
- Select use case
- Start a graph with one or more REST APIs
- Name your graph
- 任意の名前
- Confirm or modify graph ID
- そのまま確定
y
を入力してプロジェクトを作成してください。
この時、APOLLO_KEY=<YOUR_APOLLO_KEY> rover dev --graph-ref <YOUR_GRAPH_REF> --supergraph-config supergraph.yaml
と表示されます。
後ほど使用するため、コピーしておきます。
サンドボックスを実行する
- Linux/Mac
先ほどコピーした以下をそのまま実行して動作を確認します。$ APOLLO_KEY=<YOUR_APOLLO_KEY> rover dev --graph-ref <YOUR_GRAPH_REF> --supergraph-config supergraph.yaml
- Windows
コピーしたコマンドを以下のように書き直して実行してください。$ $env:APOLLO_KEY = "<YOUR_APOLLO_KEY>"; rover dev --graph-ref <YOUR_GRAPH_REF> --supergraph-config supergraph.yaml
クエリを試してみる
http://localhost:4000
にアクセスして、以下のクエリを実行してください。
query ExampleQuery {
products {
id
name
description
}
}
RESTのエンドポイントを叩いてみる
では実際に、RESTのエンドポイントをGraphQLで叩く例を試してみましょう。
今回はQiita APIからユーザー情報とユーザーが投稿した記事を一括で取得できるようにします。
準備
-
qiita.graphql
ファイルを作成 - supergraph.yamlを以下のように変更
subgraphs: products: routing_url: http://ignore schema: file: products.graphql qiita: routing_url: http://ignore schema: file: qiita.graphql federation_version: =2.10.0
全体
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.10", import: ["@key"])
@link(
url: "https://specs.apollo.dev/connect/v0.1"
import: ["@source", "@connect"]
)
@source(
name: "qiita",
http: { baseURL: "https://qiita.com/api/v2" }
)
type Query {
"A curated array of listings to feature on the homepage"
qiitaUsers: [User!]!
@connect(
source: "qiita"
http: { GET: "/users" }
selection: """
id
name
description
organization
"""
)
"A specific listing"
user(id: ID!): User
@connect(
source: "qiita"
http: { GET: "/users/{$args.id}" }
selection: """
id
name
description
organization
"""
entity: true
)
}
type User {
"ユーザーID"
id: ID!
"ユーザー名"
name: String
"自己紹介文"
description: String
"所属している組織名"
organization: String
items: [Item!]!
@connect(
source: "qiita"
http: { GET: "/users/{$this.id}/items" }
selection: """
id
title
url
created_at
updated_at
"""
)
}
type Item {
"記事ID"
id: ID!
"記事のタイトル"
title: String!
"記事のURL"
url: String!
"記事の作成日時"
created_at: String!
"記事の更新日時"
updated_at: String!
}
スキーマ
ここでは、GraphQLスキーマを拡張し、Qiita APIとの接続情報を定義しています。
- @link:Apollo FederationやConnectorsの仕様をスキーマに読み込みます。
- @source:Qiitaという名前でREST APIエンドポイントを登録します(baseURL)。
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.10", import: ["@key"])
@link(
url: "https://specs.apollo.dev/connect/v0.1"
import: ["@source", "@connect"]
)
@source(
name: "qiita",
http: { baseURL: "https://qiita.com/api/v2" }
)
Query定義
Qiitaの各エンドポイントをGraphQLのクエリとして定義します。
- qiitaUsers: Qiitaのユーザー一覧 (GET /users) を取得するクエリです。
- user(id: ID!): 特定ユーザーの情報を取得します。
type Query {
qiitaUsers: [User!]!
@connect(
source: "qiita"
http: { GET: "/users" }
selection: """
id
name
description
organization
"""
)
user(id: ID!): User
@connect(
source: "qiita"
http: { GET: "/users/{$args.id}" }
selection: """
id
name
description
organization
"""
entity: true
)
}
レスポンスデータの構造を定義
- User: Qiitaのユーザー情報。さらに items フィールドで、そのユーザーの投稿一覧も取得できます。
- @connect の {$this.id} により、User型インスタンスの id を使って動的にエンドポイントを変えて取得しています。
type User {
id: ID!
name: String
description: String
organization: String
items: [Item!]!
@connect(
source: "qiita"
http: { GET: "/users/{$this.id}/items" }
selection: """
id
title
url
created_at
updated_at
"""
)
}
参考
最後に
ミスから学び始めた技術でしたが、やってみると可能性を感じる技術でした。
GraphQLに祝福あれ。