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 | CmsIntegrationPlugin の WordPressResolver, ShopProductVariantsResolver |
| SMILE 管理操作 | 管理画面から export / import / regroup を起動・参照 | Vendure Dashboard | SmileIntegrationPlugin の SmileIntegrationAdminResolver, 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 が適切です。
- 生成済みファイルの download は
Content-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 維持 を正とします。
理由:
- caller が Storefront ではなく 外部 CMS の編集 UI / サーバー側連携である
- 検索用途が 固定形のサジェスト API で、field selection の必要性が低い
CMS_API_TOKENと署名付き header による server-to-server 契約 がすでに成立している- CMS 側へ Vendure の GraphQL schema や permission model を露出しない方が保守しやすい
実装時のルール¶
新しい API を追加する際は、次の順で判断します。
- caller は誰か
- first-party UI ならまず GraphQL
- 外部システムならまず REST
- HTTP semantics が仕様か
- redirect / download / webhook / callback / health は REST
- field selection や nested fetch が本当に要るか
- 要るなら GraphQL
- 不要なら REST の方が契約が単純
- Vendure の permission / channel / schema extension に自然に載るか
- 載るなら GraphQL を優先
- 公開・観測方法は何か
- GraphQL schema / GraphiQL で十分か
- OpenAPI / header 契約 / curl 例が必要か
ドキュメント運用¶
- GraphQL 面の利用・探索は
GraphiQLと schema を正本にする - REST 面の契約は OpenAPI / endpoint 別文書 / curl 例を正本にする
- 「UI で使うから REST に寄せる」「Swagger で見たいから GraphQL を REST 化する」といった 可視化都合だけの技術選択はしない