#architecture (3)
背景
フルスタック Web 開発では「どのバックエンド使うか」という選択肢が多い。
- Firebase Cloud Functions
- AWS Lambda
- Google Cloud Functions
- Cloudflare Workers
- Vercel Functions
- 自社 VM / Kubernetes
アンチパターン
単なる Slack webhook POST → Firebase Cloud Functions + GCP VM
課題
- 過剰エンジニアリング: インフラの複雑さが実装の 10 倍
- 学習曲線: Firebase SDK の理解 / GCP コンソール操作
- 運用コスト: 監視、ログ、スケーリング設定
- 冗長性: 単純な処理に高可用性インフラは不要
原則:逆算発想
1. 必要な処理は何か?
→ Slack Webhook 1 行の POST
2. どのくらいのスケールか?
→ コーポレートサイト、月 100 件程度の問い合わせ
3. どのインフラがそれに適切か?
→ API Gateway / Edge Function で十分
❌ Firebase(学習コスト高い)
❌ Cloud Run(常時起動 VM)
✓ CF Pages Functions(エッジで即実行、無制限)
判断表
| 必要な処理 | 推奨インフラ | 理由 |
|---|---|---|
| Webhook POST / メール送信 | CF Functions / Vercel API | 単発実行、低レイテンシ |
| CRUD API + DB | Supabase / Firebase Realtime | リアルタイム必須 |
| バッチ処理 / 長時間実行 | Cloud Tasks / Temporal | スケジュール・リトライ |
| リアルタイム双方向通信 | WebSocket (Vercel KV / Durable Objects) | ステートフル |
| 機械学習推論 | Lambda / Cloud Functions | 計算量多い |
移行ケース
Before(過剰)
Next.js (GCP App Engine)
↓
Firebase Cloud Functions
↓
Slack Webhook
- 起動:
gcloud app deploy(数分待ち) - 監視: GCP コンソール + Firebase console
- コスト: 月 $10-50(Free tier外)
After(最小化)
Astro static (CF Pages)
↓
CF Pages Functions(同一プロジェクト)
↓
Slack Webhook
- デプロイ:
wrangler deploy(秒単位) - 監視: CF dashboard 一箇所
- コスト: 月 $0(Free 10万req/日)
チェックリスト:この技術は必要か?
- 実装なしに同じ結果を得られないか?(No = 必要)
- 学習コストは実装メリットに見合うか?
- 運用オーバーヘッド(監視、スケーリング、ログ)は将来的に必要か?
- チーム全体が使いこなせるスキルセットがあるか?
- 本番環境での障害時の対応ができるか?
1 つでも No なら、もっと単純な選択肢を検討する。
学び
「機能しているから」という理由で複雑性を受け入れない。 移行時が技術選定を見直すベストタイミング。
3つの実装形態
| 形態 | 構成 | 使い分け |
|---|---|---|
| A: スキル単体 | SKILL.md | 対話的 + 軽量処理 |
| B: サブエージェント単体 | agent.md | 非対話、他から呼ばれる |
| C: ラッパーパターン | SKILL.md + agent.md | /command起動 + 重い処理は別コンテキスト |
判断フロー
対話が必要?
├─ Yes → 処理重い? → Yes: C / No: A
└─ No → /command起動したい? → Yes: C / No: B
ポイント
disable-model-invocation: trueは使わない。descriptionのトリガー条件で起動制御する方が柔軟- ラッパーパターンでは SKILL.md は薄く(委譲のみ)、実処理は agent.md に書く
- 軽量処理のagentは
model: haikuでコスト3倍削減
現状技術スタック
フロントエンド: Next.js 14.2.35 (App Router) + React 18.3.1 + TypeScript 5.x スタイリング: Tailwind CSS v3 + SCSS Module(microCMSリッチテキスト用) 状態管理: Zustand(2ストア) CMS: microCMS BaaS: Firebase(Firestore, Functions, Auth) デプロイ: Google App Engine
ページ構成: 約50ページ(LeanGoコーポレート、dejamサービス、ad-future)、動的ルート多数
移行のネック項目
| 項目 | 影響度 | 課題 | 解決策 |
|---|---|---|---|
| ISR (revalidateTag) | 高 | Next.js固有、microCMS Webhook対応が必要 | Astro APIルートでWebhook受信→オンデマンドリビルド |
| breakpoint検出 | 高 | useLayoutEffect でwindowサイズ判定、全体ローディング | CSSメディアクエリで代替、JS削減可能 |
| Firestoreクライアント | 中 | /dejam/website/ のみ | client:load Island に分離 |
| Firebase Functions | 中 | httpsCallable(‘sendMail’) | Astro APIエンドポイント or SSRで代替 |
| HubSpotフォーム | 中 | クライアント専用インタラクション | Astro Componentで Island化 |
Astro採用の優位性
Astro Islands パターン:
- ページ全体をJSで制御せず、インタラクティブ必須部分のみを「島」として独立
- ページの大部分は静的HTMLで高速配信、フォーム/カルーセル等のみJS送信
Next.jsと比較した利点:
- ファイル形式がHTML的 → デザイナーが読める
- 概念が少ない → HTML + Tailwind で完結、React hooks/Server-Client判断不要
- Claude Code との相性 → 生成コードがシンプル、副作用少、スコープ局所
- 役割分離が自然 → 静的部分(デザイナー) vs Islands/API(エンジニア)
- サイト特性に合致 → 90%以上が静的 → ゼロJS配信で最高速
データフェッチング戦略
- microCMS: Content Collections + ISR相当(オンデマンドビルド)
- JSON: readFileSync → Astro loaders に置換
- Firestore: Client Islands のみ(useEffect内で直接呼び出し)
- Firebase Functions: Astro SSR APIエンドポイントに移行
デザイナー・エンジニア作業領域分離
| 領域 | 対象 | 担当 |
|---|---|---|
| 静的マークアップ + Tailwind | ほぼ全ページ | デザイナー(.astro) |
| Islands(React/Svelte) | フォーム、カルーセル、Firestore | エンジニア |
| API, デプロイ, CMS連携 | 機能実装 | エンジニア |
リスク・注意点
- テスト未整備 → 移行時のリグレッション検知は手動確認に依存
- GAEデプロイ対応 → Node adapter 検証が必須
- breakpoint検出の移行 → CSSメディアクエリ設計の見直し
結論
大半が静的生成可能で、クライアントJS が限定的。Astro Islands は本件の要件と完全マッチ。ビルドキャッシング戦略の設計が鍵。