メインコンテンツまでスキップ

第3章 不変条件はどこで守る?“境界”の話🚪🧱✨

この章のゴール🎯

Boundaries Map

  • 「境界(きょうかい)」=入力が入ってくる入口だって説明できる🙂
  • UI / API / DB / 外部I/O が、ぜんぶ「境界」になりうるって分かる🌐🗄️📩
  • 自分のアプリで「境界マップ(入口一覧)」を作れる🗺️✨

1) まず“境界”ってなに?🚪

ひとことでいうと…

境界=“外の世界”と“中の世界”の接点👭🌍🏛️

  • 外の世界:ユーザー入力、HTTP、DB、外部サービス、ファイル、環境変数… → **何が来るか分からない(信用できない)**😵‍💫
  • 中の世界:あなたが設計するドメイン(業務ルールの中心) → 信用できる状態にしてから扱いたい🛡️✨

つまり境界は、**「危険なものが入ってくる玄関」**なのね🏠💥 ここでちゃんと止めると、家の中(ドメイン)が平和になります🕊️


2) なんで“境界”で守るの?🧠🛡️

不変条件(絶対守る約束)を守る場所がバラバラだと、こうなるよ👇😭

  • あっちでチェック、こっちでチェック… 抜け漏れが出る🕳️
  • どの画面から来た入力なのかで挙動が変わる😇😈
  • 直したつもりが別ルートから壊れる(バグ無限ループ)♾️💥

だから基本方針はこれ👇

境界で「怪しいデータ」を受け止めて検証して(Validation)中で使える形に変換して(Convert)失敗は外向けの言葉に翻訳して返す(Translate)

この4点セットが超大事だよ〜!✨


3) 境界になりやすい“4大入口” remind🧱

この章のキーワードにもなってるやつ👇 (ぜんぶ不変条件が壊れやすい入口!)💣

① UI(画面・フォーム・CLI)🎀⌨️

  • テキストボックス、選択肢、ファイルアップロード
  • “空文字”や“桁数オーバー”が簡単に来る😇

② API(HTTPの入口)🌐🚪

  • Controller / Minimal API のエンドポイント
  • クライアントが何送ってくるか分からない😵‍💫

③ DB(読み書き)🗄️🔁

  • DBから読み出した値が 想定とズレてる こともある
  • レガシー、手作業更新、移行ミス…あるある💥

④ 外部I/O(外部サービス・ファイル・メッセージ)📩💳📦

  • 決済、メール、外部API、S3、Queue、Webhook
  • “相手都合の仕様”が混ざる🌀

4) 境界を見つける“超かんたん質問”4つ👀✨

自分のアプリを思い浮かべて、これを順番に聞いてみてね🙂

  1. どこからデータが入ってくる?(入力経路)🚪

  2. どこへデータを出す?(外部へ返す/渡す)📤

  3. どこに保存・復元する?(DB/ファイル)🗄️

  4. 誰のルールに従う?(外部API/他チーム/他社)🤝

  5. 誰のルールに従う?(外部API/他チーム/他社)🤝

ここで出てきた場所が、だいたい境界候補だよ🗺️✨


5) 境界でやる仕事は“3つ+おまけ”🧰💖

A. 検証(Validation)🛡️

  • 形式チェック(空/長さ/範囲/必須)
  • 組み合わせチェック(AならB必須、など)
  • “できない入力”を早めに止める🙅‍♀️

B. 変換(Convert)🔁

  • string → int
  • string → DateTime
  • DTO → 内部モデル(この教材だと、後半で VO を作る💎)

C. 翻訳(Translate)🗣️

  • 内部のエラーを、UI/API向けの分かる形にして返す
  • 例:画面なら「この項目がダメだよ」
  • APIなら HTTP 400 + 説明、みたいに📣

おまけ:ログ・観測(Log/Trace)👀🧾

  • 境界は事故現場になりやすいので、ログがあると神🙏✨
  • ただし入力を丸ごとログに残すのは危険な場合もあるから注意ね🔐

6) ミニ題材で境界マップを作ってみよ🗺️🎀

題材:会員登録+サブスク課金💳✨

ざっくりデータの流れ(イメージ)🌊

  • 画面(フォーム)🎀 → API(登録エンドポイント)🌐 → アプリ処理(登録ユースケース)🧠 → DB(会員保存)🗄️ → 外部決済(サブスク作成)💳 → メール送信(歓迎メール)📩

ここで境界はどれ?っていうと… UI / API / DB / 決済API / メール がぜんぶ境界だよ〜!🚪🚪🚪

境界マップ(テンプレ)📋✨

下みたいに「入口台帳」を作ると、抜けが一気に減るよ😊

境界入ってくるもの“怪しい”ポイントここで守ること(例)
UIフォーム🎀文字列だらけ空白/全角/長すぎ必須・長さ・見た目の整形
APIエンドポイント🌐JSON形式・型違い400返す、エラー形を統一
DB読み込み🗄️既存データ変な値が混ざる変換時に検知・修復方針
決済API💳外部仕様エラー/タイムアウトリトライ方針・失敗の翻訳
メール送信📩外部仕様送れない/遅延キュー化・失敗時の扱い

7) 境界の“外向けエラー”を整える(API例)🌐🧱✨

API境界って「失敗の見せ方」も超大事なのね🙂 ASP.NET Core では Problem Details(RFC 7807) でエラーを返す設計が一般的になってるよ📣 さらに .NET 10 の ASP.NET Core では、Minimal API の検証(validation)と、そのエラー応答のカスタマイズに IProblemDetailsService を使える流れが用意されてるよ🧩✨ (Microsoft Learn)

例(雰囲気だけつかめればOK😊)👇

using System.ComponentModel.DataAnnotations;

var builder = WebApplication.CreateBuilder(args);

// 400(Validation)などのProblemDetailsを統一して整える✨
builder.Services.AddProblemDetails(options =>
{
options.CustomizeProblemDetails = context =>
{
if (context.ProblemDetails.Status == 400)
{
context.ProblemDetails.Title = "入力にまちがいがあるよ🥺";
context.ProblemDetails.Extensions["hint"] = "入力欄の赤いところを見てね🎀";
context.ProblemDetails.Extensions["traceId"] = Guid.NewGuid().ToString();
}
};
});

var app = builder.Build();

app.MapPost("/register", ([Required, EmailAddress] string email) =>
{
// ここは“境界”だから、受けたら検証→変換→中へ渡すのが基本🛡️🔁
return Results.Ok(new { message = "登録OK🎉", email });
});

app.Run();

ポイントはこれ👇

  • 境界では「外向けのエラー形式」を揃える🧱✨
  • 中の処理は「業務の本質」に集中できるようになる🎯

(ちなみに .NET 10 は 2025年11月11日リリースのLTSで、今ど真ん中の現役ラインだよ🧡)(Microsoft for Developers)


8) 演習:あなたのアプリで“境界マップ”を作ろう🗺️🖊️✨

Step 1️⃣ 境界を10個まで列挙してOK🙆‍♀️

例の型でメモしてみてね👇

  • UI:画面A、画面B、管理画面…🎀
  • API:POST /xxx、GET /yyy…🌐
  • DB:Usersテーブル、Ordersテーブル…🗄️
  • 外部:決済、通知、ファイル、Webhook…📩

Step 2️⃣ 各境界に「怪しいポイント」を書く💣

  • 空/負数/範囲外/null/文字種/組み合わせズレ…🧨

Step 3️⃣ 「ここで止める」or「中で守る」を分ける🧱

  • 境界:止める(入力の質を上げる)🛡️
  • 中:絶対に壊さない(後の章で型・設計で固める)💎

9) AI活用コーナー🤖💞(境界探しが爆速になるよ)

そのままコピペで使えるやつ置いとくね✨

✅ 境界候補の洗い出し

  • 「このアプリの概要は〇〇です。画面/UI、API、DB、外部サービス、バッチ、ファイル入出力の観点で“境界候補”を箇条書きで列挙して。漏れがちな境界も一緒に。」

✅ 境界ごとの“壊れ方”レビュー

  • 「境界A(例:会員登録API)で起きうる“壊れた入力”を20個出して。空/長さ/範囲/組み合わせ/悪意ある入力も混ぜて。」

✅ 境界マップの抜けチェック

  • 「この境界マップに抜けがないかレビューして。特に“非同期(キュー/バッチ)”と“DB読み込み時”の境界をチェックして。」

まとめ🎀✨

  • 境界は 外の世界と中の世界の接点🚪
  • UI / API / DB / 外部I/O は全部、事故が入りやすい入口💥
  • 境界では 検証→変換→翻訳(+ログ) をやると強い🛡️🔁🗣️
  • .NET 10(LTS)では Minimal API の検証まわりと ProblemDetails の整え方も公式に整理されてるよ📚✨ (Microsoft Learn)

次の章(第4章)は、いよいよ **入口を守る具体技:ガード節(Guard Clauses)**🛡️💨 「境界で止める」コードを、読みやすくスッキリ作る練習に入ろ〜😊🎀