コンテンツにスキップ

WordPress GraphQL API リファレンス

このドキュメントは、WordPress GraphQL API(WPGraphQL)の使用方法とクエリ例を説明します。

Storefront の通常導線は WordPress に直接アクセスせず、Vendure Shop API 経由 です。Storefront 実装で使うクライアントは apps/storefront/src/lib/cms/client.tsfetchCmsGraphQL() で、WordPress 直叩きは疎通確認や Vendure プラグイン実装時の診断用途に限定します。

エンドポイント

ローカル環境

http://localhost:8181/graphql

本番環境

https://cms.ritsubi.co.jp/graphql

基本的なクエリ

イントロスペクション

GraphQLスキーマを確認する:

query {
  __schema {
    types {
      name
      description
    }
  }
}

利用可能なクエリを確認

query {
  __type(name: "Query") {
    fields {
      name
      description
    }
  }
}

お知らせ(Announcement)クエリ

お知らせ一覧取得

query AnnouncementList($first: Int!) {
  announcements(where: { orderby: { field: DATE, order: DESC } }, first: $first) {
    nodes {
      id
      databaseId
      title
      date
      slug
      link
      announcementMeta {
        isFeatured
        relatedLink
      }
    }
  }
}

変数:

{
  "first": 10
}

フィーチャー済みお知らせ取得

フィーチャー済み(isFeatured: true)のお知らせのみを取得する場合は、クライアント側でフィルタリングします。

フォールバッククエリ

メインクエリが失敗した場合のフォールバック:

query AnnouncementFallbackList($first: Int!) {
  contentNodes(where: { contentTypes: ANNOUNCEMENT }, first: $first) {
    nodes {
      ... on Announcement {
        id
        databaseId
        title
        date
        slug
        link
        announcementMeta {
          isFeatured
          relatedLink
        }
      }
    }
  }
}

キャンペーン(Campaign)クエリ

キャンペーン一覧取得

query CampaignsList($first: Int!) {
  campaigns(where: { orderby: { field: DATE, order: DESC } }, first: $first) {
    nodes {
      id
      databaseId
      title
      date
      slug
      link
      featuredImage {
        node {
          sourceUrl
          altText
          mediaDetails {
            width
            height
          }
        }
      }
      campaignMeta {
        order
        image {
          node {
            ... on MediaItem {
              sourceUrl
              altText
              mediaDetails {
                width
                height
              }
            }
          }
        }
      }
    }
  }
}

変数:

{
  "first": 10
}

フォールバッククエリ

query CampaignsFallbackList($first: Int!) {
  contentNodes(where: { contentTypes: CAMPAIGN }, first: $first) {
    nodes {
      ... on Campaign {
        id
        databaseId
        title
        date
        slug
        link
        featuredImage {
          node {
            sourceUrl
            altText
            mediaDetails {
              width
              height
            }
          }
        }
        campaignMeta {
          order
          image {
            node {
              ... on MediaItem {
                sourceUrl
                altText
                mediaDetails {
                  width
                  height
                }
              }
            }
          }
        }
      }
    }
  }
}

メインバナー(Main Banner / ACF Options)

ホームヒーローは ACF Options の「メインバナー」で管理します。WPGraphQL では mainBannerOptions から取得し、Storefront は Vendure Shop API の wordPressBanners を利用して正規化済みデータを取得します。

メインバナー取得

query MainBanner {
  mainBannerOptions {
    homeHero {
      slides {
        title
        lead
        media {
          type
          image {
            desktop {
              node {
                sourceUrl
              }
            }
            mobile {
              node {
                sourceUrl
              }
            }
            alt
          }
          video {
            desktop {
              node {
                mediaItemUrl
              }
            }
            mobile {
              node {
                mediaItemUrl
              }
            }
          }
        }
        displayPeriod {
          startAt
          endAt
        }
        trackingId
        campaignId
        scheduleMode
        locations
        destinationUrl
        linkedProductSlugs
        linkedCollectionSlugs
        subjectSetIds
        targetCustomerGroupIds
        targetCustomerCodes
      }
    }
  }
}

クエリオプション

where句のオプション

並び替え(orderby)

where: {
  orderby: {
    field: DATE  # DATE, TITLE, MODIFIED, etc.
    order: DESC  # ASC, DESC
  }
}

日付フィルタ

where: {
  dateQuery: {
    after: "2024-01-01"
    before: "2024-12-31"
  }
}

ステータスフィルタ

where: {
  status: PUBLISH  # PUBLISH, DRAFT, etc.
}

pagination(ページネーション)

first(最初のN件)

first: 10

after(カーソルベース)

after: "cursor-string"

エラーハンドリング

エラーレスポンス例

{
  "data": null,
  "errors": [
    {
      "message": "Cannot query field 'unknownField' on type 'Announcement'",
      "path": ["announcements", "nodes", 0, "unknownField"],
      "extensions": {
        "category": "graphql"
      }
    }
  ]
}

部分データの許可

allowPartialData: true を設定すると、エラーがあってもdataが存在する場合はデータを返します:

const data = await fetchCmsGraphQL({
  query: MY_QUERY,
  allowPartialData: true,
});

テスト方法

curlでテスト

curl -X POST http://localhost:8181/graphql \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query { __typename }"
  }'

GraphQL Playground

WordPress管理画面からGraphQL Playgroundにアクセス:

http://localhost:8181/wp-admin/admin.php?page=graphql-playground

Storefront からの疎通確認

Storefront 導線の確認は WordPress 直の /graphql ではなく、Vendure 経由の /shop-api を確認します。

curl -X POST http://localhost:3000/shop-api \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query { wordPressAnnouncements(limit: 1) { totalCount } }"
  }'

テストスクリプト

プロジェクトにはテストスクリプトが用意されています:

cd apps/storefront
./test-campaign-manual.sh

パフォーマンス最適化

フィールドの選択

必要なフィールドのみを取得することで、レスポンスサイズを削減:

# ❌ 悪い例: すべてのフィールドを取得
query {
  campaigns {
    nodes {
      id
      title
      content
      excerpt
      # ... 多くのフィールド
    }
  }
}

# ✅ 良い例: 必要なフィールドのみ取得
query {
  campaigns {
    nodes {
      id
      title
      campaignMeta {
        order
      }
    }
  }
}

ページネーション

大量のデータを取得する場合は、ページネーションを使用:

query {
  campaigns(first: 10, after: "cursor") {
    pageInfo {
      hasNextPage
      endCursor
    }
    nodes {
      id
      title
    }
  }
}

セキュリティ

CORS設定

WordPress側でCORS設定を行う必要があります:

// functions.php
add_action('graphql_http_request_headers', function($headers) {
    $allowed = [
        'https://order.ritsubi-platform.com',
        'https://medical.ritsubi.co.jp',
        'https://order.ritsubi.co.jp',
    ];
    $origin = $_SERVER['HTTP_ORIGIN'] ?? '';
    if (in_array($origin, $allowed, true)) {
        $headers['Access-Control-Allow-Origin'] = $origin;
    }
    $headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS';
    $headers['Access-Control-Allow-Headers'] = 'Content-Type';
    return $headers;
});

認証(将来の拡張)

現時点では認証なしでアクセス可能ですが、将来的に認証を追加する場合は:

const headers = {
  Authorization: `Bearer ${token}`,
};

const data = await fetchCmsGraphQL({
  query: MY_QUERY,
  headers,
});

参考資料