← ブログ一覧
技術ブログ

ヘッドレスCMSにGraphQL ― リレーションを1リクエストで取得する

平原 典彦 — Tesseraを開発しているエンジニア。ヘッドレスCMSとAI連携に関心があります。

記事に紐づく著者やカテゴリを一緒に表示したい――ヘッドレスCMSでよくある要件ですが、RESTだと地味に往復が増えます。TesseraがGraphQLを採用しているのは、この「関連データの取得」を1リクエストで完結させるためです。

RESTの往復問題

記事一覧を表示するのに、RESTだとこうなりがちです。

  1. 記事一覧を取得
  2. 各記事の著者IDから著者を引く
  3. カテゴリIDからカテゴリを引く

記事が10件あれば、著者・カテゴリの取得で追加のリクエストが積み上がります(N+1)。埋め込み展開のオプションがあるCMSもありますが、取得したいフィールドまで細かく指定できるとは限りません。

GraphQLなら1リクエスト

Tesseraでは、必要なリレーションを含めて1回のクエリで取れます。

{
  blogPosts(limit: 6, sort: CREATED_AT_DESC) {
    title
    slug
    author { name }
    category { name slug }
    coverImage { url }
  }
}

記事・著者・カテゴリ・アイキャッチが、これだけで一度に返ってきます。欲しいフィールドだけを指定するので、オーバーフェッチ(使わないデータまで取る)も起きません。

TesseraのGraphQL Playground。blogPostsを問い合わせると、紐づく著者(author)とタグ(tags)までネストして1レスポンスで返っている様子

記事→著者→タグを、1回のクエリでまとめて取得。欲しいフィールドだけを指定できるので、オーバーフェッチも起きない。

スキーマは実行時に自動導出される

ここがヘッドレスCMSにGraphQLを載せる上での技術的な肝です。コンテンツタイプはユーザーが管理画面で自由に増やしたり、フィールドを足したりします。つまりGraphQLスキーマが実行時に動的に変わるわけです。

Tesseraは、あなたが定義したコンテンツタイプからGraphQLの型・クエリ・フィルタ・ページングを自動導出します。コンテンツタイプを1つ承認すれば、その型のクエリがすぐ使える状態になります。スキーマを手で書く必要はありません。

  • 各コンテンツタイプ → 対応するオブジェクト型と一覧クエリ
  • リレーションフィールド → ネストして辿れる関連
  • 一覧には limit / offset / sort / フィルタが自動で付く

読み取り系は、無料プランでもフル開放

GraphQL API(とMCPの読み取り系)は、無料プランでも制限なく開放しています。差別化の中核体験そのものを課金で制限しない、という方針です。まず1リクエストでリレーションを取る快適さを、そのまま試せます。

まとめ

  • リレーションを含むデータは、GraphQLなら1リクエストで取れる(RESTの往復・N+1を避ける)
  • 欲しいフィールドだけ指定できるので、オーバーフェッチが起きない
  • コンテンツタイプの増減に追従して、GraphQLスキーマは実行時に自動導出される
  • 読み取り系は無料プランでもフル開放

「AIがCMSの構造を理解する」のがTesseraのコンセプトですが、その構造を素直に引き出せるAPI(GraphQL)があると、フロント側もシンプルに書けます。