コンテンツにスキップ

REST / GraphQL 境界方針

項目 内容
更新日 2026-05-06
更新者 Copilot
対象 Vendure Server の Shop API / Admin API 拡張、外部連携 API

概要

本プロジェクトでは、Vendure 標準の Shop API / Admin API を GraphQL の正面導線としつつ、外部連携・Webhook・callback・download・監視面は REST を採用します。

判断の主眼は「どの技術が好きか」ではなく、誰が呼ぶかHTTP の意味づけが必要か契約をどう公開・保守するか です。

結論

  • GraphQL を第一候補にする領域
  • Storefront や Vendure Dashboard のような first-party UI から使う read / write
  • 1 回の呼び出しで複数エンティティを横断し、必要なフィールドだけ選びたい 問い合わせ
  • Vendure の permission、channel、custom field、schema extension と 同じ文脈で扱いたい 業務操作
  • REST を第一候補にする領域
  • Webhook / callback / redirect / file download / health check のように HTTP semantics が主役の入口
  • 外部 CMS、基幹、決済事業者など、GraphQL client を前提にしない third-party / server-to-server 連携
  • 署名検証、status code、header、binary response、HTML response を契約の一部として扱う API

判断マトリクス

判断軸 GraphQL を選ぶ条件 REST を選ぶ条件
caller Storefront / Vendure Dashboard / first-party frontend 外部 CMS / 基幹 / 決済事業者 / 監視系
取得形態 画面ごとに欲しい項目が変わる、ネスト取得が多い 入出力が固定、単機能でよい
HTTP semantics 200 系 JSON が中心 status code / redirect / download / webhook 受信が主役
契約公開 GraphQL schema / GraphiQL / 型生成で十分 OpenAPI / curl / header 契約の明示が重要
認証 Vendure の session / token / permission に載せたい HMAC 署名、shared secret、IP/WAF など外部連携向け
変更耐性 UI 都合の field selection を許容したい シンプルで固定的な契約を長く保ちたい

現行 API 面の分類

GraphQL を正とする面

主な用途 consumer 実装の代表例
Shop API 拡張 Storefront 向けの商品・顧客・価格・同意・配送・レコメンド取得 Storefront CustomerManagementPlugin, CommercialRulesPlugin, ShippingCalculatorPlugin, ConsentSystemPlugin, WishlistPlugin, RecentlyViewedPlugin, CoPurchaseRecommendationPlugin, MaintenanceModePlugin
Admin API 拡張 Vendure Dashboard 向け管理操作、設定、業務ワークフロー Vendure Dashboard AdminExtensionsPlugin, CustomerManagementPlugin, PointsSystemPlugin, ReportPlugin, ConsentSystemPlugin, SecurityLogPlugin, MaintenanceModePlugin
CMS 正規化 read Storefront / Dashboard から WordPress コンテンツを Vendure 経由で取得 first-party UI CmsIntegrationPluginWordPressResolver, ShopProductVariantsResolver
SMILE 管理操作 管理画面から export / import / regroup を起動・参照 Vendure Dashboard SmileIntegrationPluginSmileIntegrationAdminResolver, SmileOrderExportFieldResolver

REST を正とする面

主な用途 consumer 実装の代表例
基幹 Webhook 出荷完了通知を受けて受注を更新 基幹システム POST /system-integration/shipment/notify
決済 callback / redirect 決済事業者 callback、ホストページ遷移、browser return SB Payment / browser /sb-payment/*
CMS 検索 API CMS 編集画面で SKU / 商品 / コレクション候補を検索 外部 CMS / WordPress /cms-api/sku-search, /product-search, /collection-search, /campaign-search
ファイル download export 済みファイルを binary で返す Vendure Dashboard 管理者 GET /smile-export/download
監視・運用 live / ready / version / metrics platform / monitoring /health/live, /health/ready, /version, /metrics

[!IMPORTANT] /health/ready /version /metrics直接 TCP 接続元 (socket.remoteAddress) が loopback / private network のときだけ 200 を返し、それ以外は 404 になります。X-Forwarded-For の中身は信頼判定に使いません(isTrustedObservabilityRequest)。Fly のように proxy が private network 経由で接続してくる構成では透過しますが、Cloudflare 等 public IP からの直接到達は 404 になるため、外部 monitoring は storefront 側の /api/health/* proxy か内部 wireguard 経由で叩く前提です。

境界が混在する代表例

1. WordPress / CMS 連携

  • WordPress コンテンツを Storefront へ渡す面は GraphQL が適切です。Storefront は商品や顧客状態と合わせて必要な field だけ取得したいため、Vendure の Shop API 拡張に寄せる価値があります。
  • CMS 編集時の検索補助は REST が適切です。WordPress 管理画面や外部 CMS から必要なのは、署名付きの単純な検索 endpoint とフラットな JSON であり、GraphQL schema の理解を前提にしない方が運用が安定します。

したがって、CMS 連携は一律に GraphQL でも一律に REST でもなく、consumer ごとに分ける 方針を正とします。

2. SMILE 連携

  • エクスポートの起動・履歴参照・設定操作は Vendure Dashboard から使うため GraphQL が適切です。
  • 生成済みファイルの downloadContent-Disposition と binary response が必要なため REST が適切です。

つまり、同じ業務機能でも、操作面は GraphQL、受け渡し面は REST という分割を許容します。

3. 決済連携

  • callback、cancel、redirect、simulator は 外部事業者や browser 遷移の契約であり、GraphQL に寄せる理由がありません。
  • 戻り値も OK / NG、302 redirect、HTML response が中心で、HTTP 契約そのものが仕様です。

このため、決済 callback / return 系は REST を維持します。

cms-api の判断

今回の棚卸しでは、cms-api/*REST 維持 を正とします。

理由:

  1. caller が Storefront ではなく 外部 CMS の編集 UI / サーバー側連携である
  2. 検索用途が 固定形のサジェスト API で、field selection の必要性が低い
  3. CMS_API_TOKEN と署名付き header による server-to-server 契約 がすでに成立している
  4. CMS 側へ Vendure の GraphQL schema や permission model を露出しない方が保守しやすい

実装時のルール

新しい API を追加する際は、次の順で判断します。

  1. caller は誰か
  2. first-party UI ならまず GraphQL
  3. 外部システムならまず REST
  4. HTTP semantics が仕様か
  5. redirect / download / webhook / callback / health は REST
  6. field selection や nested fetch が本当に要るか
  7. 要るなら GraphQL
  8. 不要なら REST の方が契約が単純
  9. Vendure の permission / channel / schema extension に自然に載るか
  10. 載るなら GraphQL を優先
  11. 公開・観測方法は何か
  12. GraphQL schema / GraphiQL で十分か
  13. OpenAPI / header 契約 / curl 例が必要か

ドキュメント運用

  • GraphQL 面の利用・探索は GraphiQL と schema を正本にする
  • REST 面の契約は OpenAPI / endpoint 別文書 / curl 例を正本にする
  • 「UI で使うから REST に寄せる」「Swagger で見たいから GraphQL を REST 化する」といった 可視化都合だけの技術選択はしない

関連ドキュメント