【C#/Blazor】実務Webアプリ開発編 (12)システム構成を設計する ~アーキテクチャ選定と技術スタック~
実務Webアプリ開発編です。前回の「要件定義を書く」では、誰が使い、何を作り、何を今回は作らないかを整理しました。
今回はその続きとして、要件をどんな構成で実現するかを考える「システム構成」を扱います。
題材は MentorApp の spec.md です。ブラウザ、Blazor Server、データベース、外部IdPの関係を整理しながら、技術選定の考え方を見ていきましょう。
以下のような方に役立つ内容となっています。
- システム構成図に何を書けばよいか迷っている
- 技術スタックの選び方を実例ベースで学びたい
- 開発環境と本番環境の違いをどう整理すればよいか知りたい
- Blazor Server と外部認証を含む構成の全体像をつかみたい
システム構成は、「このアプリがどの部品でできていて、どう繋がるか」を見える形にする作業です。
ここが整理できると、実装で使う技術や責務分担がかなり明確になります。
MentorAppのドキュメント・コード一式はGitHubに置いてあります。
システム構成設計でやること
システム構成を考えるときは、どの機能をどの部品で受け持つかを整理します。
要件定義が「何を作るか」を整理したものだとすれば、システム構成は「どう実現するか」の大枠を決めたものです。
たとえば Web アプリなら、ブラウザだけで完結するのか、サーバーを持つのか、認証は自前か外部サービスか、データはどこに保存するのかを決める必要があります。
この整理を先にしておかないと、ログイン方式やデータ保存先が決まらず、実装の前提そのものが定まりません。
そのまま進めると、どこに何を書くかがぶれやすくなり、手戻りも大きくなります。
MentorApp のシステム構成では、特に次の4点を決めています。
- 共通技術スタック:何のフレームワークやORMを使うか
- 環境別構成:開発環境と本番環境で何を切り替えるか
- 認証とデータ保存の場所:外部IdPとDBの役割分担をどうするか
- レイヤー構成:アプリ内部をどう責務分割するか
つまり、システム構成ではインフラの配置だけでなく、外側の接続関係と内側の責務分担を一緒に整理することが大事です。
このあと spec.md を見ながら、MentorApp でどう決めているかを具体的に確認していきましょう。
あとで見返したときに「なぜこの技術を選んだのか」がわかる状態にしておくと、構成を見直すときの判断軸になります。
MentorAppのspec.mdを読む
ここからは MentorApp の 4. システム構成 を読みながら、何を整理しているのかを分解して見ていきます。
どういう意図でこの形になっているかに注目しながら、一緒に読んでいきましょう!
共通技術スタックを先に固定する
spec.md「4. システム構成 / 共通技術スタック」に対応します。以下が記載されています。
- .NET 10 / ASP.NET Core / Blazor Server を土台にする
- データアクセスは Entity Framework Core を使う
- UI は Bootstrap 5、ログは Serilog、テストは xUnit v3 + Playwright を使う
環境ごとの差分より前に、全体で共通に使う技術を先に固定することで、「開発環境では別のフレームワーク」「本番では別の実装」というブレを防げます。
Blazor Server は、画面の処理を主にサーバー側で持つ方式です。ブラウザ側に複雑な実装を抱えにくいため、C#中心で画面とサーバーをまとめて作りやすい利点があります。
Blazorの基本や、Serverモード・WASMモードの違いや使い分けについては以下の記事も参考にしてください。
また、ORM(Object-Relational Mapping) を EF Core に統一しておくと、「C#のオブジェクトをどうDBに保存するか」を同じ流儀で扱えます。
データの読み書きの書き方が揃うので、DBアクセスを担う層(Repository等)の実装でも一貫した書き方を保ちやすくなります。
今回は、新規開発かつ厳しい性能要件もないため、EF Coreを選定しています。
もし、既存のDBやSQLコード資産などがあったり、高い性能要件がある場合は、SQL を直接使う(Dapper 等)ことも選択肢になるでしょう。
Blazorアプリ・EFCoreの基本については以下のBlazor Todoアプル開発シリーズも参考にしてください。
開発環境は「外部依存なしで試せる」形にする
spec.md「4. システム構成 / Development 環境(典型例)」に対応します。以下が記載されています。

- ブラウザはローカルの Blazor Server と通信する
- DB は InMemory / SQLite / LocalDB を切り替えられる
- 認証は Mock を使い、外部IdPなしで動作確認できる
開発環境の狙いは、すぐ動かせることです。毎回クラウドのDBや認証設定が必要だと、試すまでのハードルが上がります。
MentorApp では、ローカルで完結できる構成を用意しつつ、必要なら設定変更で外部IdPや Azure SQL にも繋げられるようにしています。
この「普段は軽く、必要なときは実運用に近づける」という構成はかなり実践的です。開発速度と確認精度の両方を確保しやすくなります。
認証も Mock を用意しているので、OIDC 設定がまだなくても画面遷移や認可の流れを先に確認できます。外部依存を切り離した開発体験を作っているわけです。
Mock 認証を用意しておくと、外部サービスの準備を待たずに画面確認を進められます。
Mock認証があると、外部サービス待ちをしなくていいだけじゃなくて、テストでも同じログイン状態を再現しやすそう。
その通りです。自動テストでは毎回同じ条件でログイン済みユーザーを用意したいので、Mock は E2E テストや動作確認の安定化にも役立ちます。
本番環境は Azure を前提に役割分担する
spec.md「4. システム構成 / Production 環境(典型例)」に対応します。以下が記載されています。

- アプリ本体は Azure App Service 上の Blazor Server として動かす
- DB は Azure SQL Database を使う
- 認証は Entra ID または Google などの外部IdPに任せる
本番構成では、アプリ・DB・認証基盤を分けて考えているのがポイントです。
アプリは Azure App Service、データは Azure SQL Database、ログインは外部IdPという分担にすると、それぞれの責務が明確になります。
認証を外部IdPへ委ねると、アプリ側でパスワード保管やログインUIを一から持たずに済みます。
つまりこの構成は、「何でも自前で持つ」のではなく、得意な基盤に任せるところは任せるという設計です。
認証を外に出すと、自分のアプリではログインの中身を全部持たなくてよくなるんだ。たしかに責務がかなり減りそう。
はい。アプリは「認証する仕組み」よりも、「認証されたユーザーに何を許可するか」に集中しやすくなります。
Blazorアプリと外部IdP(EntraId)の連携や、Azure App Serviceへデプロイする方法については以下の記事も参考にしてください。
アプリ内部はレイヤーで責務分割する
spec.md「4. システム構成 / レイヤー構成」に対応します。以下が記載されています。
- Web 層はUI表示とユーザー操作の受付を担当する
- Application 層はユースケース実行とトランザクション制御を担当する
- Domain 層はビジネスルールを担当する
- Infrastructure 層は永続化や外部連携を担当する
システム構成は外側の接続関係だけでは終わりません。アプリ内部をどう分けるかも、かなり重要です。
MentorApp では、クリーンアーキテクチャを前提に、Web / Application / Domain / Infrastructure の4層で責務を分けています。
依存関係を図示すると以下になります。矢印は「依存の向き」を表しています。どの層も、最終的には中心の Domain 層に向かって依存する構造になっているのがポイントです。

この分割があると、画面表示の処理と、業務上守るべきルールを分けて考えやすくなります。
例えば「トピックをクローズできる条件」は Domain や Application で扱い、Web 層は入力受付と表示に集中できます。
また、DB や外部認証の仕組みが変わっても、業務ルールまで一緒に書き換えずに済みやすくなります。
つまり、外部サービスに近い処理は外側の層に寄せ、アプリの中心となるルールは内側に残す構成にしているわけです。
クリーンアーキテクチャの利点や、具体的にこのアーキテクチャに従ってどのように実装していくかは、このシリーズのなかで解説します!
設計上の判断ポイント
ここからは、MentorApp のシステム構成における設計判断の意図を整理します。
Blazor Server を選ぶと、UIとサーバーの距離が近い
MentorApp では Blazor Server を採用しています。これは、C# で UI もサーバー側も扱いやすいという学習上の利点だけでなく、構成上の単純さにも意味があります。
Blazor Server では、画面操作のたびにフロントエンド用APIを自分で細かく設計しなくても、C#のコンポーネントからそのまま処理を書き進めやすいです。
フロントエンドとバックエンドの境界を強く意識しなくてよいぶん、最初の構成をシンプルに保ちやすくなります。
これは他のWebフレームワークではあまり一般的でない、Blazor(Serverモード)の大きな特徴ですね。
一方で、各ユーザーがサーバーとつながり続ける前提なので、利用者が増えるとサーバー側の負荷を見積もる必要があります。
また、通信が切れると画面操作に影響しやすい面もあります。このトレードオフを理解したうえで、MentorApp では構成のわかりやすさを優先しています。
開発環境と本番環境で「同じアプリ」を保っている
Development と Production で切り替えているのは、主に DB と認証プロバイダーです。アプリ本体の考え方は大きく変えていません。
これはとても重要で、環境ごとに別アプリのような構成になると、ローカルでは動くのに本番では違う、というズレが増えます。
MentorApp では、環境によって変わる部分を DB と認証まわりに絞っています。
アプリ本体は同じまま、appsettings で接続先や認証プロバイダーを切り替えられるので、ローカル確認と本番運用の差を小さく保ちやすいです。
認証を外部IdPに任せると、アプリの責務が整理しやすい
ログイン機能を自前で持つと、パスワード管理、リセット、ロックアウト、連携など、扱う範囲が一気に広がります。
MentorApp では OIDC による外部認証を選び、アプリ側ではユーザーのロールや、アプリ内で管理するユーザー情報との紐づけに集中する前提を置いています。
この切り分けは、ログイン後に外部IdPの情報をアプリ用の権限情報へ変換する処理や、認可設計にも繋がります。
つまり、認証はシステム構成だけの話ではなく、その後のアプリ設計にも効いてくる判断です。
構成を決める段階で、もう認可やユーザー管理の実装方針まで影響してくるんだね。
そうです。だからシステム構成は単なる配線図ではなく、以後の設計を支える前提条件として見るのが大切です。
Azure 構成を早めに意識すると、公開までの道筋が見えやすい
MentorApp では、Production の典型例として Azure App Service と Azure SQL Database を置いています。
公開を見据えた構成を早めに考えておくと、接続文字列、認証設定、データ保存先などの前提が揃いやすくなります。あとで無理やりクラウド対応するより、かなり進めやすいです。
小さな個人開発でも、「最終的にどこへ置くか」を軽く決めておくのはおすすめです。ローカル完結だけで考えるより、構成の判断がぶれにくくなります。
まとめ
- システム構成は実現方法の大枠を決める:外側の接続関係と内側の責務分担を整理する
- 共通技術スタックを先に固定する:環境ごとの差分より前に共通部分を決めると設計がぶれにくい
- 開発環境は軽く、本番環境は役割分担を明確にする:Mock認証や切り替え可能なDBで開発しやすくしつつ、公開時は App Service・Azure SQL・外部IdPへ責務を分ける
- レイヤー構成まで含めて考える:Web / Application / Domain / Infrastructure の分割が、後の実装や保守性に効いてくる
- 構成の判断は後の実装方針に影響する:認証、永続化、UI実装、デプロイまで一貫して関わる
システム構成を整理すると、要件を実現するための技術的な前提が定まり、以降の設計や実装の方針が立てやすくなります。
MentorApp では、ブラウザ・Blazor Server・DB・外部IdPの接続関係と、アプリ内部の4層構成を合わせて整理し、外側と内側の両方から責務の分担が見える形になりました。
次回は、この構成の上に載るデータモデルを設計していきます。User / Mentorship / Topic / Message の関係を見ながら、エンティティと関連の考え方を整理しましょう。
システム構成は、要件を実装へつなぐための土台です。どの部品が何を担うかを整理すると、設計も実装もぐっと見通しやすくなります。
引き続き、データモデルの設計について一緒に学んでいきましょう!





