SaaS・Web API
B2Bの自社サービス、公開API
推奨:TypeScript
推奨
TypeScript
- 少人数なのでフロントと同じTypeScriptに揃える(§2-10 手順3)
構成行を開くと詳細(乗り換える条件・根拠・費用・習熟度)
フロントNext.js+shadcn/ui+TanStack Query
Next.js
既定:アプリ(SSR・フルスタック)フロントエンド
乗り換える条件
- TanStack StartVercel依存を避けたい、クライアント主体で型安全なルーティングを重視するとき
- React Router(フレームワークモード)Remix系の資産があるとき
代替:画面Elixir(BEAM)
既定は Phoenix LiveView(サーバー主導でリアルタイムUI)。フロントをReactで作りたいとき に乗り換える。
成長したら → ECS/Cloud Run(コンテナ)§24
- きっかけ
- 費用の増加、AWSに集約したい
- 最初からの備え
- Next.jsのstandalone出力でコンテナ化できる状態を保つ。Vercel固有の機能への依存を最小にする
ケース別の構成§19
- EC(独自要件が多い)フロント:Next.js+shadcn/ui
- 自社SaaS(B2B)フロント:Next.js+shadcn/ui+TanStack Query
- toCサービス(Web+モバイル)Web:Next.js
- AI/LLMプロダクトフロント:Next.js(ストリーミング表示)
- 個人開発・MVPTS全部入り:Next.js+Supabase+Vercel
習熟度
shadcn/ui
ケース別の構成§19
- EC(独自要件が多い)フロント:Next.js+shadcn/ui
- 業務システム・社内ツール(TypeScript構成)UI:shadcn/ui+TanStack Table(編集が重いならAG Grid)
- 自社SaaS(B2B)フロント:Next.js+shadcn/ui+TanStack Query
TanStack Query
バックエンドHono(軽量・どこでも動く・型安全なRPC)
Hono
既定:HTTPフレームワークTypeScript(Node.js)
乗り換える条件
ケース別の構成§19
習熟度
API@hono/zod-openapi(Zodスキーマからルートと仕様を同時に定義)
DBPostgreSQL(テナントIDカラム+Row Level Security)
PostgreSQL
採用の根拠§22-2
OSSでライセンス費用がかからない。AWS、GCP、Azureを含む主要クラウドがすべてマネージド版を提供している。拡張機能(pgvector、pg_bigm)でベクトル検索や日本語全文検索までこなせるため、専用DBを増やさずに済む
「MySQLの方が一般的では」→ 機能・標準SQLへの準拠・拡張性で優位。移行ツールも揃っている
ケース別の構成§19
習熟度
ジョブpg-boss(Postgresベース、§4-3)
pg-boss
既定:ジョブキューTypeScript(Node.js)
乗り換える条件
- BullMQ(Redis/Valkey)秒間数百件を超える、またはValkeyが既にあるとき(§23-1)
- Inngest/Trigger.devサーバーレス環境でワークフロー(リトライ・待機・ステップ実行)が必要なとき
課金Stripe Billing
インフラECS on Fargate+RDS+Terraform
ECS on Fargate
既定:AWSを使うどこで動かすか
乗り換える条件
- Lambdaリクエストがまばらでコールドスタートを許容できるとき
- ECS Express Mode構成を最小にしたい小規模案件
App Runnerは新規受付を終了したため選ばない
費用の注意§25
- 主な課金の軸
- vCPU・メモリの稼働時間
- 膨らみやすい要因
- 過大なタスクサイズ、最小タスク数の設定しすぎ
- 対策
- 実測に合わせて調整する。検証環境はSpotを使う
ケース別の構成§19
- EC(独自要件が多い)インフラ:ECS on Fargate、Cloudflare(CDN・WAF・Waiting Room)
- 業務システム・社内ツール(TypeScript構成)デプロイ:Render(AWSならECS on Fargate、オンプレならコンテナでVM)
- 自社SaaS(B2B)インフラ:ECS on Fargate+RDS+Terraform
- データ基盤・バッチ実行:RenderのCron Job(AWSならECSのスケジュールタスク)
習熟度
RDS
既定:AWSを使うどこで動かすか
乗り換える条件
- Lambdaリクエストがまばらでコールドスタートを許容できるとき
- ECS Express Mode構成を最小にしたい小規模案件
App Runnerは新規受付を終了したため選ばない
Terraform
採用の根拠§22-2
開発・検証・本番で同じイメージを使えるため、環境差による不具合が起きにくい。クラウド移行時もコードから再構築できる
「学習コストが高い」→ テンプレート化しており、案件ごとの差分は小さい
ケース別の構成§19
- 自社SaaS(B2B)インフラ:ECS on Fargate+RDS+Terraform
習熟度
分析・機能フラグPostHog
PostHog
既定:Webサイトのアクセス解析プロダクト分析・機能フラグ
乗り換える条件
- Cloudflare Web Analytics静的サイトでCookieなしの最小限の計測だけ欲しいとき
- Plausibleセルフホストもできる軽量な解析が欲しいとき
- GA4取引先やマーケティング担当がGA4のレポートを求めるとき
既定:A/Bテストプロダクト分析・機能フラグ
ケース別の構成§19
- 自社SaaS(B2B)分析・機能フラグ:PostHog
- toCサービス(Web+モバイル)分析:PostHog
- モバイルアプリ単体分析:PostHog
習熟度
監視Sentry+OpenTelemetry+Grafana Cloud
Sentry
既定:エラー監視監視・可観測性・運用
既定:エラー時のユーザー問い合わせプロダクト分析・機能フラグ
採用の根拠§22-2
障害の検知と原因特定の時間を短縮できる。計装をOpenTelemetryにしておけば、監視サービスを後から変更できる
「費用がかかる」→ 無料枠・サンプリングで調整できる。障害の長期化による損失の方が大きい
費用の注意§25
- 主な課金の軸
- エラー数、トレースのスパン数、セッションリプレイ数、ログ量
- 膨らみやすい要因
- 同じエラーの大量発生、トレースの全量送信
- 対策
- トレースのサンプリング率を設定する。既知のノイズを除外する
ケース別の構成§19
- EC(独自要件が多い)監視:Sentry+Grafana Cloud
- 自社SaaS(B2B)監視:Sentry+OpenTelemetry+Grafana Cloud
- AI/LLMプロダクト監視:Sentry+OpenTelemetry
- データ基盤・バッチ監視:Sentry(Cron Monitoringで実行漏れを検知)
- モバイルアプリ単体監視:Sentry
習熟度
OpenTelemetry
既定:計装Elixir(BEAM)
既定:計装(トレース・メトリクス)監視・可観測性・運用
採用の根拠§22-2
障害の検知と原因特定の時間を短縮できる。計装をOpenTelemetryにしておけば、監視サービスを後から変更できる
「費用がかかる」→ 無料枠・サンプリングで調整できる。障害の長期化による損失の方が大きい
ケース別の構成§19
- 自社SaaS(B2B)監視:Sentry+OpenTelemetry+Grafana Cloud
- AI/LLMプロダクト監視:Sentry+OpenTelemetry
習熟度
Grafana Cloud
ケース別の構成§19
- EC(独自要件が多い)監視:Sentry+Grafana Cloud
- 自社SaaS(B2B)監視:Sentry+OpenTelemetry+Grafana Cloud
§19-6の構成を、選んだ条件に合わせて一部差し替えている
構成図 自社SaaS(B2B)
flowchart TB
U["利用企業"] --> FE["Next.js"]
FE --> CL["Clerk/WorkOS"]
FE -- "OpenAPI" --> API["Go API<br/>ECS Fargate"]
API --> DB[("PostgreSQL<br/>RLS でテナント分離")]
API --> RV["River ワーカー"] --> DB
API --> ST["Stripe Billing"]
API --> OT["OpenTelemetry"] --> GF["Grafana Cloud"]最初に決めること:マルチテナントの分離方式、SSO対応の時期、監査ログの範囲。
作り始める
共通の準備
# 言語・ツールのバージョン固定(使う言語だけ)
mise use node@lts pnpm@latest
mise use go@latest
mise use ruby@latest
mise use python@latest uv@latest
# Gitフックと依存更新
pnpm add -D lefthook && pnpm exec lefthook install
# renovate.json を置き、GitHubでRenovateアプリを有効化する自社SaaS・Goバックエンド(§19-6)
mkdir api && cd api
go mod init example.com/app/api
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
go install github.com/pressly/goose/v3/cmd/goose@latest
go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest
go get github.com/jackc/pgx/v5 github.com/riverqueue/river
sqlc init
goose -dir db/migrations create init sql