株式会社renue
AI導入・DXの悩みをプロに相談してみませんか?
AIやDXに関する悩みがありましたら、お気軽にrenueの無料相談をご利用ください。 renueのAI支援実績、コンサルティングの方針や進め方をご紹介します。
Strapiを直接叩かせないBFF設計:なぜFastAPIを間に挟むのか
Strapiは2026年現在、Node.js系ヘッドレスCMSの事実上の標準として広く使われています。REST API v4・GraphQL・プラグインエコシステム・構造化データ対応が整っており、マーケティングチームが記事を入稿し、フロントエンド(Next.js等)が配信する、という典型構成は多くの企業で採用されています。しかし、企業規模のAI活用が進むにつれて、「Strapiを直接フロントエンドから叩く」「Strapiを直接AIエージェント(Claude Code等)に触らせる」設計では立ち行かない論点が次々に出てきます。
本記事では、「FastAPIをBFF(Backend for Frontend)としてStrapiの前段に配置する」設計パターンを共有します。トークン非露出、プロジェクト単位の入稿先切替、品質エビデンスゲート、機密スキャン、重複検査、バックアップ、Webhook受信といった、Strapiの標準設定だけでは満たせない要求を、FastAPIレイヤーで体系的に扱う実装パターンを、実装粒度で整理します。
関連記事としてマルチテナントFastAPIバックエンド設計ガイド、Celery + Azure運用ガイド、LLMOps実践ガイドもご参照ください。
Strapi直接接続がダメな7つの理由
理由1:APIトークンが露出する
StrapiのAPIトークンは非常に強力で、漏洩すればコンテンツの改ざん・削除・不正入稿ができます。フロントエンドにトークンを埋め込む設計は論外ですが、AIエージェントに環境変数で直接渡す設計も、プロンプトインジェクションや誤ったログ記録で漏洩するリスクがあります。BFFレイヤーでトークンをDB管理し、呼出側には一切露出させないのが安全な設計です。
理由2:プロジェクト・環境別の設定切替が扱いづらい
Strapi直接接続の設計では、ステージング・本番・プロジェクトごとに接続先を切り替えるたびに、クライアント側の設定を変更する必要があります。BFFに「プロジェクトごとの入稿先設定」のマッピングテーブルを置けば、クライアントはプロジェクト識別子を渡すだけで、BFFが正しいStrapi環境を選択して処理できます。
理由3:品質ゲート・ガバナンスの追加実装が必要
「機密情報が含まれている記事を自動入稿しない」「ファクトチェック未実施の記事をブロックする」「重複記事を入稿させない」といった品質ゲートには、Strapi側のカスタム処理またはBFFでの追加実装が必要です。FastAPI BFFレイヤーで、入稿前に構造的な品質エビデンスをPydanticで強制し、機密スキャンを実行し、重複検査をかける設計にすれば、これらを一箇所で管理できます。
理由4:Strapi APIの癖を吸収できない
Strapi v4のREST APIは、`pagination[limit]`、`filters[field][$contains]`、`populate`、`fields` などの特殊なクエリパラメータ形式を持ちます。また、`blocks` コンポーネント(rich-text等)の入稿は特定のJSON構造を要求します。これらの癖をクライアント側(特にAIエージェント)に学習させるのは非効率で、BFFで吸収するのが合理的です。
理由5:監査ログ・バックアップが弱い
Strapi単体でも監査プラグインはありますが、「入稿時のエビデンス・スキャン結果・チェック担当・承認プロセス」を統合的に記録するには不十分です。FastAPI BFFレイヤーで、入稿リクエストごとに監査用バックアップと監査ログを作成すれば、後から完全なトレーサビリティが得られます。
理由6:複数ソースの統合が必要
記事入稿の多くは、Strapi単体では完結せず、「社内DBの企業情報」「外部KWユニバース」「GA4/GSC実績」「画像ライブラリ」「AI生成プレビュー」など複数ソースの統合が必要です。BFFレイヤーでこれらを束ねることで、クライアントは単一のエンドポイントを叩くだけで済みます。
理由7:セキュリティ脆弱性のパッチ適用が重要
Strapi本体に脆弱性が見つかった場合、BFF経由なら「一時的にBFF側で書込操作をブロックする」などの緊急対応が可能です。直接接続設計では、クライアント側すべてを止めるしかなく、影響範囲が大きくなります。
Strapi + BFF設計の一般例
レイヤー構成
[AIエージェント / CLI / フロントエンド]
↓ (認証JWT + プロジェクト識別子)
[FastAPI BFF]
├─ 認証・認可
├─ 入力バリデーション(Pydantic)
├─ 品質エビデンスゲート
├─ 機密情報スキャン(Haiku等)
├─ 重複検査
├─ カテゴリ解決(自動分類)
├─ バックアップ記録
└─ CMS APIクライアント (REST v4)
↓ (APIトークン)
[Strapi CMS]
↓ (配信)
[Next.js / モバイルアプリ / AI検索]
主要コンポーネントの役割
- CMS APIクライアント(REST v4ラッパー):`base_url` と `token` をコンストラクタで受け取り、記事の一覧取得・作成・更新・削除に相当するメソッドを提供します。HTTPエラーは `CmsApiError(status_code, detail, response_body)`(本記事の例示用の例外名) という専用例外に変換し、接続エラーは502、Strapi側の4xx/5xxはそのまま透過します。タイムアウトは30秒を標準設定にします。
- プロジェクト単位の入稿先管理テーブル:「ProjectID → Strapi base_url + token + SSL verify」のマッピングをDBテーブルで管理します。プロジェクト単位で異なるStrapi環境を使うマルチテナント運用が可能になります。
- 品質エビデンスのスキーマ定義:入稿リクエストのbodyに含めることを必須にします。調査記録や機密チェックなど複数のフィールドに、文字列レベルの構造制約(`min_length=40〜80`、正規表現でURL/hits/keyword等の必須マーカー)を課し、Pydantic `field_validator` で実行時バリデーションします。
- 機密情報スキャナー(AI二次確認):入稿本文を独立した軽量モデル(例:Claude Haiku 4.5)に匿名名義で投げ、機密情報・顧客名・内部プロジェクトコードの混入を検出します。fail-closed設計で、スキャナー自体がエラーを返した場合も入稿をブロックします。
- 重複検査:入稿前にStrapi側の既存記事リストを検索し、類似タイトル・類似スラグを検出します。意図的な差別化記事は `--allow-similar true` で明示バイパスできる設計にします。
- カテゴリ解決:(1) 明示ID指定 → (2) slug指定 → (3) タイトルから決定論的ルール → (4) Haiku/Opus fallback、の4段階優先順位でカテゴリを自動解決します。
- バックアップ記録:入稿成功時に別テーブルに全文とメタデータをスナップショット保存します。将来の復元・監査・差分比較に使います。
CMS APIクライアントの実装ポイント
認証情報を安全に管理する
Strapiトークンは環境変数で渡すのではなく、DBにプロジェクトごとに格納します。FastAPIルーターの最初で「プロジェクト識別子 → Strapi接続情報」をDBから取得し、CMS APIクライアントをインスタンス化します。AIエージェントやクライアントコードはトークンに一切触れません。
例外を統一型にラップする
requests.exceptionsやHTTPエラーを、そのままクライアントに返すのではなく、`CmsApiError(status_code, detail, response_body)`(本記事の例示用の例外名) という専用例外型にラップします。これにより、ルーター層では `except CmsApiError as e: raise HTTPException(status_code=e.status_code, detail=e.detail)` のシンプルなパターンで処理できます。
SSL verifyを切替可能にする
本番は必ず `ssl_verify=True` ですが、開発環境やセルフホスト検証環境では `False` にしたいことがあります。CMS APIクライアントのコンストラクタに `ssl_verify` オプションを置き、デフォルトをTrueに設定します。Falseは明示的に指定しないと使えない設計にすることで、事故を防げます。
Strapi v4の特殊クエリを吸収する
Strapi v4のクエリパラメータは `pagination[limit]=25&pagination[start]=0&sort=createdAt:desc&filters[title][$contains]=AI` のように、ネストしたキーを使います。CMS APIクライアント側で 一覧取得メソッドで通常のPython引数を受け取り、内部でこの形式に変換します。呼出側はStrapi固有の知識不要で使えます。
blocks形式への変換
本記事の構成例では、Strapi v5に `blocks` というDynamic Zoneと `shared.rich-text` コンポーネントを定義し、本文を `blocks: [{"__component": "shared.rich-text", "body": ""}]` という構造で入稿します。CMS APIクライアント側で `body: str` を受け取り、この形式に自動変換するヘルパーを用意すると、呼出側(特にAIエージェント)が迷いません。入稿後は `populate=*` でblocksが空でないことを検証する「blocks_verified」ステップを追加することで、無言の失敗を防げます。
品質ゲートとPydantic強制
記事入稿BFFで最も重要なのが品質ゲートです。品質エビデンスのスキーマは、調査記録と機密チェックの各項目で構成します。
- 調査記録(検索した一次情報のURLを含む)
- 機密情報チェックの実施記録
- 独自視点の根拠
- 社内リポジトリ調査の記録
いずれも単語だけの記入では通らないよう、文字数・形式の制約付きで必須化します(具体的なフィールド名や閾値は運用ごとに設計します)。
これらのフィールドはすべて `Field(..., min_length=...)` で必須化し、`field_validator` で「単語のみ(none、なし、該当なし等の無意味な埋め込み)」を拒否する二重ガードを組み込みます。これにより、必要な項目の欠落や形式違反を構造的に検出できます。ただし、記載内容の真偽は別途検証が必要です。
機密情報スキャナー統合
Pydanticの文字列制約では「本文に顧客名が含まれている」ような意味論的問題は検出できません。そこで、入稿直前に本文を軽量モデル(Claude Haiku 4.5)に投げ、機密情報混入を検出するステップを追加します。
設計原則
- fail-closed:スキャナーがエラーを返した場合、API障害・タイムアウト・予期しない出力のいずれでも、入稿をブロックします。「スキャナーが動かなかったから許可」は絶対にやりません。
- 独立コンテキスト:スキャナーを呼び出す際は、呼出元の組織情報(例:renueの事業内容)を一切渡しません。匿名の独立モデルとして、「この本文に顧客名・人名・内部コードネーム・未公開数値が含まれているか」だけを判定させます。
- 自社情報の例外:プロンプトで「自社の事業名・サービス名の言及は正常な営業活動」「競合・顧客の特定は禁止」と明確に区別します。区別がないと、自社サービス言及まで「機密」と誤判定するケースが頻発します。
- 両方の入口に配置:create_article と update_article の両方のエンドポイントにスキャナーを配置します。create側だけ守っても、updateで迂回されれば意味がありません。
入稿フローの全体シーケンス
- クライアント(AIエージェント・CLI・Web UI)が 入稿用のエンドポイント に入稿リクエストを送る
- FastAPIが認証・認可を実行
- Pydanticで 品質エビデンス を含む全フィールドをバリデート
- 接続情報を保持するテーブルから プロジェクト識別子 → Strapi接続情報を取得
- 重複検査(articles-list --search)を実行、類似記事があれば409 Conflict(`allow_similar=true` なら通過)
- 機密情報スキャナーで本文を検査(fail-closed)
- カテゴリ解決(明示ID → slug → 決定論的ルール → LLM fallback)
- CMS APIクライアント経由で Strapi POST /articles を実行
- 成功時、`blocks` が空でないか `populate=*` で検証
- 監査用バックアップにスナップショット保存
- クライアントに成功レスポンス(作成されたStrapi IDと検証結果付き)
Webhook受信パターン
双方向連携が必要な場合、Strapi側のWebhook設定で `entry.create`、`entry.update`、`entry.publish` 等のイベントをFastAPI BFFに通知します。BFF側で以下を実行できます。
- 公開記事のキャッシュクリア(Next.js ISR等)
- 社内DBへの連携(記事メタデータを別テーブルに同期)
- Slack通知(新規公開記事を関係者にブロードキャスト)
- SEO分析ツールへの通知(一般記事はサイトマップ更新やSearch Consoleでの再クロール依頼を検討。Indexing APIは対象ページが限定)
- AI Overviewの再評価(Citation観測システムへのトリガー)
Webhookエンドポイントでは、Strapi側に設定した認証ヘッダーを検証します。HMAC署名を使う場合は、送信側の署名生成と受信側の検証も追加実装します(公式Webhookセキュリティ)。オープンエンドポイントにすると、外部から偽のWebhookが送られる攻撃が可能になります。
Strapi + BFF設計の基本原則
原則1:Strapiトークンは絶対にクライアントに露出させない
BFF以外の場所にトークンが存在する状態は禁忌です。環境変数、フロントエンドコード、Gitリポジトリ、Slackメッセージ、AIエージェントコンテキスト、どこにもトークンを置きません。
原則2:プロジェクト単位の入稿先テーブルを必ず用意する
Strapi接続情報を「アプリ全体でグローバル1つ」にすると、複数テナント・複数環境対応で行き詰まります。最初からプロジェクト単位のマッピングテーブルで設計します。
原則3:品質エビデンスをPydanticで構造強制する
boolean チェックボックス(`--web-search true`)は偽装通過が可能です。品質エビデンス のような文字列構造制約モデルで、実施記録そのものを必須にします。
原則4:機密スキャンはfail-closedで二重ガード
Pydantic構造制約 + Haiku意味論スキャンの二段構えにします。スキャナー障害時は必ずブロックします。
原則5:入稿前に必ず重複検査する
同じタイトル・類似スラグの記事を誤って二重入稿する事故を防ぎます。意図的な差別化が必要な場合のみ明示バイパス(`allow_similar=true`)を許可します。
原則6:入稿後はblocks検証を必ず実施する
Strapi側で `blocks` が空のまま保存される事故が稀に起きます。入稿直後に `populate=*` で取得し直し、blocks_verifiedフラグをレスポンスに含めます。
原則7:監査用バックアップにスナップショット保存する
後からの復元、監査、差分比較のために、入稿成功時に全文と全メタデータを別テーブルに保存します。
原則8:CMS連携用の専用例外型で透過する
Strapi側の4xx/5xxはstatus_codeと本文を保持したまま、専用例外型でFastAPIルーターに伝播させます。ルーター層で `HTTPException` に変換します。
原則9:カテゴリ解決は4段階フォールバック
明示ID → slug → 決定論的ルール → LLM fallbackの優先順位で、常にカテゴリが決まる設計にします。カテゴリ未設定で入稿されることを構造的に防ぎます。
原則10:create/update両方のエンドポイントに同じゲートを配置
create側だけセキュリティを固めても、update側が脆弱なら意味がありません。両方に同じ品質ゲート・機密スキャン・バックアップを配置します。
本番で遭遇する6つの落とし穴
落とし穴1:Strapi v4とv5のblocks構造の違い
Strapi v5ではレスポンスのフラット化やdocumentIdの導入があり、クライアント側の対応が必要です。 `blocks` の構造は記事のコンテンツ型・コンポーネント定義に従うため、移行後のスキーマに合わせて入稿JSONも確認します(公式REST APIリファレンス)。
落とし穴2:Strapi側でカテゴリIDが変わっている
Strapi上でカテゴリを手動再作成すると、IDが変わってBFF側のマッピングが壊れます。カテゴリIDはslug解決経由で動的に取得するのが安全です。
落とし穴3:Update時にblocksが消える
Strapiの標準REST APIの更新はPUTで行い、送信した項目を部分更新します。未指定の `blocks` をBFF側で空配列に変換すると既存値を失うため、省略と空配列を区別してください。 `blocks` 自体を編集する場合は、必要に応じて既存値を読み出して更新内容を組み立てます(公式更新API)。
落とし穴4:HTTPタイムアウト不足
大きな記事(数十KB以上)の入稿で30秒タイムアウトに当たることがあります。記事サイズに応じて60秒〜120秒に拡張するか、非同期ジョブ化します。
落とし穴5:Haikuスキャナーのプロンプト暴発
スキャナーのプロンプトが厳しすぎると、自社サービス名の言及まで「機密」と判定されて入稿がブロックされます。自社言及は正常、競合・顧客言及のみ禁止、と明確に区別するプロンプト設計が必要です。
落とし穴6:レート制限による一括入稿失敗
大量記事を短時間で入稿すると、Strapi側のレート制限で途中から失敗します。一括入稿ジョブはBFF側でrate limit対応(sleep挿入、バックオフ、再試行)を組み込みます。
まとめ:StrapiはAPIを開けっぱなしにする時代ではない
2026年のヘッドレスCMS運用は、「Strapiを直接開けて誰でも叩ける」時代から、「BFFレイヤーで品質・セキュリティ・監査・AI統合を担保する」時代に移りました。FastAPIはPython製AI/LLMエコシステムとの親和性が高く、Pydanticによる強力なバリデーション、Haiku等の軽量LLMでの二次チェック、機密スキャン、重複検査、バックアップなどを体系的に組み込めます。本記事の10原則と6落とし穴を押さえれば、エンタープライズ品質のStrapi運用が内製可能です。
renueは、複数事業でStrapi + FastAPI BFF構成を内製運用してきた実体験から、設計レビュー・実装支援・品質ゲート構築・機密スキャナー統合・Webhook連携の伴走支援を提供しています。「既存のStrapi直接接続を安全なBFF構成に移行したい」「品質ゲートを入れたいが設計に迷っている」「AIエージェントにStrapiを触らせる設計を相談したい」などのご相談をお受けしています。
Strapi + BFF設計の導入相談
renueは、複数事業でStrapi + FastAPI BFF構成を内製運用する実体験から、設計レビュー・実装支援・品質ゲート構築・機密スキャナー統合・Webhook連携の伴走支援を提供しています。Strapi直接接続からの安全な移行、AIエージェント統合、マルチテナント対応など、実装粒度でご相談をお受けしています。
関連記事
- マルチテナントFastAPIバックエンド設計2026
- Celery + Redis + Azure Container Apps Jobs 本番運用ガイド2026
- LLMOps実践ガイド2026
- 生成AIセキュリティ完全ガイド2026
- Function Calling完全ガイド2026
- MCP完全ガイド2026
- AIコーディングエージェント徹底比較2026
- プロンプト vs RAG vs ファインチューニング比較2026
あわせて読みたい
サービス・採用に関する公開情報は、renue公式サイトをご確認ください。




