system-design について
system-design は、現在の要件を満たす最もシンプルな構成を選び、その根拠を記録するソフトウェア設計向けスキルです。データストア、API、認証、キャッシュ、ジョブキュー、ホスティング、ファイル構成を扱います。
主な機能
- 01設計前に要件を分類
- 02既存の環境とサービスを調査
- 03アーキテクチャ選択の既定案を提示
- 04変わりうるベンダー情報を確認
- 05推奨案を作成して記録
活用シーン
- 01新規プロジェクトのデータベースと API の選定
- 02サービス分割やデプロイ単位追加の検討
- 03認証、キャッシュ、バックグラウンドジョブ方式の決定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ noobygains/ godmode --skill system-designインストール後、Claude Code で/system-designを入力して読み込まれたか確認します。
同梱ファイルreferences/hosting-and-services.md
詳細
システム設計
アーキテクチャを構成するすべての要素には、保守するコードがあり、費用がかかり、障害の原因にもなります。このスキルでは、プロジェクトが今抱えている要件を満たす最もシンプルな構成を選び、新しいものよりユーザーがすでに利用しているものを優先し、その理由を記録します。複雑さを加えるには、現在の具体的な要件が必要です。「いつか必要になるかもしれない」では、何も正当化できません。
最優先の原則
NO STRUCTURAL COMPLEXITY WITHOUT A CURRENT, NAMED REQUIREMENT
例外はありません。回避策もありません。近道もありません。
使用する場面
必須:
- データベース、API スタイル、認証方式、キャッシュ、キュー、ジョブ実行ツールを選ぶ場合。
- モノリスにするかサービスに分けるかを決める場合、または新たにデプロイ可能な要素を追加する場合。
- ホスティング、ストレージ、メール、検索、決済、マネージドサービスを選ぶ場合。
- 新しいプロジェクトのファイルやモジュールを整理する場合。
- ユーザーから「何を使うべきか」「どこでホストすべきか」「どうすればスケールできるか」「X に移行すべきか」と尋ねられた場合。
省略可:
- ユーザーがすでに技術スタックを選んでいて、その実装を求めている場合:その選択を尊重して実装します(重大なリスクがあれば一度指摘し、そのまま進めます)。
- 既存のアーキテクチャ内でのバグ修正や小規模な変更。
プロトコル
-
要件を列挙し、それぞれを分類します。 データ、認証、ファイル、ジョブ、リアルタイム処理、メール、決済、検索、ホスティングなどのニーズごとに、今すぐ必要(これがないとリリースできない)、まもなく必要(実際の利用開始から数週間以内に必要となる根拠がある)、あると便利、または推測にすぎないと分類します。設計の対象は最初の2つだけです。分類が不明確な場合は、ユーザーに一度に1つずつ質問します。
-
ユーザーがすでに持っているものを調べます。 マシンとプロジェクトの状況を把握するため、
godmode:environment-awarenessを実行します。インストール済みのデータベースやランタイム、コンテナツール、ログイン済みのクラウドおよびホスティングの CLI、稼働中のサービス、既存の依存関係、サービスを参照する設定を確認します。また、ユーザーや所属組織がすでに契約しているアカウントやプラットフォームについても確認します。既存のもので要件に合うものがあれば、新しいものより優先します。 -
以下の判断表に示すデフォルトから始めます。各デフォルトは、ほとんどのプロジェクトをカバーする最もシンプルな選択肢です。
-
具体的な要件がある場合に限り、デフォルトから変更します。 変更の理由として、要件を併記します。「キュー:画像処理に40秒かかり、リクエストをブロックしてはならないため。」この一文を書けない場合は、デフォルトを維持します。
-
選択の根拠となる、変わり得る事実をすべて確認します。 サービスの制限、無料枠、料金、リージョン、ランタイムのサポート状況は、
godmode:groundingを通じてベンダーの最新ページで確認し、出典を引用します。ホスティングの条件は頻繁に変わります。料金や制限を記憶に頼って引用してはいけません。 -
システムが特殊な場合は、参考アーキテクチャを探します(
godmode:reference-first、アーキテクチャの参考資料)。 -
代替案と切り替えの条件、意図的に採用しなかったものを添えて、以下の形式で推奨案を提示します。
-
コンテキスト、決定、影響、出典を記した簡潔な決定記録をプロジェクトのドキュメントに残し、会話が終わっても理由がわかるようにします。
判断表
モノリスかサービスか
| 状況 | 選択 |
|---|---|
| 新規プロジェクトで、チームが1つ | モノリス(デフォルト)。機能ごとに整理します |
| チーム同士の作業が干渉するほどコードベースが成長している | モジュール境界を厳格に定めたモジュラーモノリス |
| 具体的な根拠があり、あるコンポーネントを今すぐ独立してスケールまたはデプロイする必要がある | そのコンポーネントだけを切り出します |
| 別々のチームが独立したドメインを担当し、リリースサイクルも異なる | それぞれのチーム境界に沿ってサービス化します |
Martin Fowler の指摘によると、成功したマイクロサービスシステムはほぼ必ずモノリスから始まっています。一方、最初からマイクロサービスとして構築されたシステムは、深刻な問題に陥ることがよくあります。最大級の Rails コードベースの1つを持つ Shopify は、マイクロサービスではなくモジュラーモノリスを選びました。
データベース
| 要件 | 選択肢 |
|---|---|
| リレーショナルデータ、トランザクション、複数ユーザー(ほとんどのアプリケーション) | PostgreSQL(デフォルト) |
| 単一サーバーまたは組み込み型、書き込みの同時実行が少なめ、最もシンプルな運用 | SQLite:一度に書き込めるのは1つですが、書き込みにかかる時間は数ミリ秒です。SQLite の開発者によると、1日のアクセス数が10万件未満のサイトなら問題なく動作するはずです |
| 形状が可変のレコードが一部ある | ドキュメントデータベースの前に、PostgreSQL の jsonb カラムを使います |
| アプリケーションデータのテキスト検索 | 検索エンジンの前に、PostgreSQL の全文検索を使います |
| キャッシュ、セッション、レート制限カウンター、一時データ | 必要になった場合に限り、Redis または互換ストアを使います |
| データベースの範囲を超える検索関連度、ファセット、スケール | 専用の検索エンジン |
| 製品の主要な処理となる時系列、グラフ、分析ワークロード | 根拠に基づいて選定した専用ストア |
要件に合うなら、ユーザーがすでに運用しているデータベースを使います。2つ目のアクセスパターンで独自のストアが明らかに必要になるまでは、データベースは1つにします。
API スタイル
| 状況 | 選択肢 |
|---|---|
| CRUD、公開 API またはパートナー API、ブラウザークライアント | JSON を使った REST(デフォルト)。設計の詳細は godmode:reference-first を参照してください |
| ネストされたデータに対する多様なクライアントの要件、クライアント側で制御するクエリ | GraphQL |
| 計測されたスループット要件がある内部サービス間通信、ストリーミング | gRPC |
| サーバーからブラウザーへのプッシュ | 一方向ストリームには Server-Sent Events、双方向には WebSockets |
| 他のシステムへのイベント通知 | 署名付き Webhook(Standard Webhooks) |
フルスタックフレームワークに組み込まれたサーバー関数は、そのフレームワークのフロントエンドで使う分には問題ありません。別のクライアントが必要になった場合にのみ、独立した API を追加します。
認証
| 状況 | 選択肢 |
|---|---|
| 1つのサイトで独自のユーザーを扱う Web アプリ | フレームワークで定評のある認証ライブラリを使った、安全な HttpOnly Cookie によるサーバーサイドセッション(デフォルト) |
| ソーシャルログインまたはエンタープライズ向けサインイン | 保守されているライブラリまたはプロバイダーを介した OAuth 2.0 / OpenID Connect |
| サードパーティまたは別オリジンから利用される独立した API | リフレッシュ機能付きの有効期間の短いアクセストークン、またはサーバー間通信向けの API キー |
| すぐに洗練されたホスト型 UI、組織、SSO が必要 | ユーザーがコストとベンダーロックインを受け入れる場合は、マネージド ID プロバイダー |
パスワードハッシュ化、セッション処理、トークン検証を一から実装してはいけません。ステートレストークンは追加の仕組みがなければ有効期限前に失効させられませんが、セッションは失効させられます。セキュリティレビューについては godmode:security-protocol と OWASP Authentication Cheat Sheet を参照してください。
キャッシュ
次の3つすべてに当てはまる場合にのみ、キャッシュを追加します。パフォーマンスの問題が計測済みであること、クエリやコードを単純に修正できないこと、データの読み取りが書き込みよりはるかに多く、多少古くても問題ないことです。
| レイヤー | 使用する場合 |
|---|---|
| HTTP キャッシュと CDN | 静的アセットと公開ページ(最初に検討する、最も安価な方法) |
| プロセスメモリ内 | インスタンスが1つで、データ量が少ない場合 |
| 共有キャッシュ(Redis または互換ストア) | 複数のインスタンスで同じキャッシュデータを使う必要がある場合 |
| マテリアライズドビュー | データベース内の高コストな集計 |
デフォルトではキャッシュを使いません。すべてのキャッシュについて、出荷前に無効化ルールを文書化する必要があります。
キューとバックグラウンドジョブ
| 要件 | 選択肢 |
|---|---|
| リクエスト内で処理が完了する | 直接呼び出し(デフォルト) |
| 時折発生する時間のかかる処理、再試行、すでに PostgreSQL を利用している | Postgres ベースのジョブキュー(例:Node.js 向けの pg-boss) |
| ジョブが多く、すでに Redis を利用している | Redis ベースのキュー(Node.js 向けの BullMQ、Python 向けの Celery) |
| 失敗後に再開する必要がある複数ステップのワークフロー、サーバーレスホスティング | 耐久性のあるワークフローサービス(例:失敗したステップから再試行する Inngest) |
| リプレイ可能で、多数のコンシューマーが利用する大量のイベントストリーミング | ボリュームの根拠がある場合は、Kafka などのログベースブローカー |
| スケジュールされたタスク | まずホストの cron またはスケジューラーを使います |
ホスティングとサービス
ユーザーがすでに利用しているものを優先し、そのうえでワークロードの特性に合わせて選びます。各ベンダーの最新の制限と料金ページへのリンクを含む比較表は、hosting-and-services.md にあります。ルールは次のとおりです。
- 要件に合うデプロイ先をすでに利用している場合は、そこを使い続けます。
- フレームワークに公式のホスティング先があり、ユーザーが満足している場合は、そのホスティング先をデフォルトにします。
- トラフィックが安定していて、コンテナーを使い、細かく制御したい場合は、VPS またはコンテナープラットフォームを選びます。
- トラフィックの変動が大きい、または少なく、静的コンテンツが中心の場合は、静的ホスティングとサーバーレス関数を組み合わせます。
- 要件に合うなら、データベース、認証、ストレージをカバーする 1 つのプロバイダーを、複数のプロバイダーを組み合わせて使うより優先します。
ファイル構成
技術レイヤーではなく機能ごとに整理し、1 つの変更が 1 つのディレクトリで完結するようにします。
src/
billing/
billing.routes.ts
billing.service.ts
billing.repository.ts
billing.test.ts
accounts/
...
shared/
db.ts
auth.middleware.ts
logger.ts
既存のプロジェクトでは、レイヤーごとの構成であっても、そのレイアウト(godmode:codebase-conventions)に従います。新しいプロジェクトでは、godmode:project-bootstrap でセットアップします。
推奨事項の提示
Requirements
- <need>: required now / required soon / nice to have (deferred) / speculative (dropped)
Already available
- <databases, runtimes, CLIs, accounts found>
Recommended
| Layer | Choice | Why (requirement, and what the user already has) | Source |
Expected running cost: <from the vendor's current pricing page, dated>, or "free tier covers current scale" with the limit cited.
Alternative and when to switch
| Layer | Alternative | Switch when <measurable trigger> |
Deliberately not used
- <service or pattern>: <why it is not needed now>
規模に見合った内容にします。週末のプロジェクトなら、5 行で十分です。
認知の落とし穴
| よくある理由付け | 実際のところ |
|---|---|
| 「あとでマイクロサービスが必要になるかもしれない。」 | あとから切り出すことはできますが、先走って分割したものを統合するのは大変です。まずはモノリスから始めます。 |
| 「NoSQL のほうが柔軟だ。」 | PostgreSQL では JSON を保存できます。スキーマのない柔軟性は、たいてい混乱を招きます。 |
| 「今は誰もが X を使っている。」 | 人気があることは要件ではありません。このプロジェクトに必要なものは何か、ユーザーがすでに使っているものは何かを確認します。 |
| 「JWT のほうが安全だ。」 | JWT は失効させるのが困難です。単一サイトなら、セッションのほうがシンプルです。 |
| 「速度を上げるにはキャッシュが必要だ。」 | まず計測します。遅さの原因の多くはクエリや N+1 であり、キャッシュがないことではありません。 |
| 「キューがあればスケーラブルになる。」 | キューを導入すると、管理対象が 1 つ増えます。リクエスト内で処理が完了しない場合に使います。 |
| 「サーバーレスは常に安い。」 | トラフィックの特性によります。このワークロードに対する最新の料金を確認します。 |
| 「無料枠のことは覚えている。」 | 無料枠や制限は変更されます。ベンダーのページをその時点で確認し、出典を明記します。 |
ガードレール
決して行わないこと:
- まだ必要のないスケールを見越してインフラを追加する。
- ユーザーがすでに何を利用しているかを確認せずに、新しいサービスを推奨する。
- 最新の出典を確認せずに、価格、制限、無料枠について述べる。
- ユーザーがすでに利用している 1 つのサービスで足りるのに、複数のマネージドサービスを組み合わせる。
- ユーザーが選んだ技術スタックを覆す。リスクは一度だけ伝え、そのまま構築する。
必ず行うこと:
- 選択する前に、すべての要件を分類する。
- デフォルトから逸脱する場合は、その理由となる要件を併記する。
- 測定可能な切り替え条件とともに、代替案を示す。
- 採用しなかったものと、その理由を伝える。
- 出典とともに決定を記録する。
関連項目
godmode:environment-awareness:ユーザーがすでに利用しているものの一覧を提供します。ホスティングやサービスの選定では、常に最初に確認します。godmode:rationale:このスキルが実装方法を決める前に、その機能をそもそも作る必要があるかを検討します。godmode:reference-first:リファレンスアーキテクチャ、API、スキーマ、CI の参照情報を提供します。godmode:grounding:ベンダーの制限、料金、機能を検証します。godmode:security-protocol:認証、データフロー、シークレットの取り扱いをレビューします。godmode:performance-tuning:キャッシュやスケーリングを変更する前に計測します。godmode:project-bootstrap:新しいリポジトリで、選択した構成をセットアップします。