本文へ移動

2026-06-01 時点の資料です。読みやすさのために、一部の文字の色を濃くしています。

Backend · Clean architecture

バックエンドの設計Backend

業務処理(API 側)のコードは、放っておくと「画面の都合・データベースの都合・業務ルール」が 1 か所に混ざり合い、少し直すたびに別の場所が壊れる状態になりがちです。松葉は最初に、役割の異なる 4 つの層に分け、依存(参照)の向きを内側へ一方通行に揃える「クリーンアーキテクチャ」という骨格を用意しました。これにより、外側(画面やデータベースの都合)が変わっても、中心の業務ルールは影響を受けにくくなります。

実装済み: 4 層の骨格と共通の入口処理 今後: 各業務処理(UseCase)を 4 層の上に載せる
01

役割で分けた 4 つの層Four layers

層は外側から、受付(Presentation)→ 段取り(Application)→ 中心の業務ルール(Domain)の順に並び、外部接続(Infrastructure)が中心の「約束(契約)」を実装します。矢印(依存)はすべて中心の Domain へ向かいます。これが「一方通行」の意味です。

図 01 · 依存はすべて中心(Domain)へ向かう一方通行
リクエストPresentation受付・ルーティング認証ミドルウェアApplicationUseCase業務の段取りDomain(中心)業務モデル・ルール外部との「約束(契約)」他の層に依存しない依存依存InfrastructureDB アクセス・外部サービス連携(Gateway)Domain の「約束」を実装して差し込む依存外側が変わっても中心は影響を受けにくい

「依存性の逆転」という工夫: 普通に作ると、業務ルール(中心)がデータベース(外側)に依存してしまい、データベースを替えると中心も書き直しになります。松葉は逆に、中心の Domain が「こういう操作ができること」という約束(契約)だけを定め、外側の Infrastructure がその約束を実装して差し込みます。これにより、外側の都合の変化が中心に波及しにくくなります。

層責務(役割)
Presentation
受付
HTTP リクエストの受け取りと応答、ルーティング(行き先の振り分け)、認証ミドルウェア。「外の世界」との接点
Application
段取り
UseCase。1 つの業務の流れ(例: ファイル一覧を取得する)を組み立てる。実際の DB 操作は下の層へ任せる
Domain
中心
業務モデルとルール、外部との「約束(契約)」の定義。他の層に依存しない、もっとも安定した中心
Infrastructure
外部接続
DB アクセス・外部サービス連携の実装(Gateway)。Domain が定めた約束を実際に果たす
02

守るべき 3 つの規則Three rules

層を分けるだけでなく、層を跨ぐときの規則を決めて、コード品質チェックで機械的に守らせています。いずれも「あとで困らないため」の予防です。

規則 1 — 段取り役(UseCase)はデータベースを直接触らない: UseCase はあくまで業務の流れを組み立てる役で、実際の DB 操作は下の層(Gateway)に任せます。これにより、業務ルールのテストを、本物のデータベース無しで行えます。

規則 2 — 1 回のリクエスト = 1 つのまとまった処理(トランザクション): 1 つの操作の中で複数のデータ更新があっても、「全部成功」か「全部取り消し」のどちらかになります。中途半端な状態が残りません。

規則 3 — 外部への通知・メール送信などを、その場で直接呼ばない: メール送信や Drive 操作のような「外部への副作用」は、DB の取り消しが効きません。そこで、いったん発信箱(Outbox)に書き留め、別の仕組みが後追いで確実に送ります(詳細は「イベント駆動の整合性」へ)。

このアプリでの例「ファイル一覧を取得」する処理は、受付(Presentation)がリクエストを受け、段取り役(UseCase)が「この人が見てよい範囲のファイルを取る」という流れを組み立て、外部接続(Gateway)が実際にデータベースへ問い合わせます。最後はデータベース側の行レベルセキュリティ(RLS)が、見てよい行だけを返します。各層がそれぞれの役割に集中できます。
03

業務 API の土台The API skeleton

この骨格の上で、業務 API(matsuba-api)の共通の入口処理を実装しました。すべてのリクエストが必ず通る共通処理(ミドルウェア)5 種と、稼働状態を外から確認する生存確認エンドポイント 3 種です。

共通処理(ミドルウェア)役割
authログイン済みか・誰かを確認(未ログインは拒否)
error処理中のエラーを、利用者に返す適切な形へ変換
loggerリクエストごとの記録(後から追跡できるログ)
oidc-verifyクラウド内部からの正規の呼び出しかを検証(なりすまし防止)
require-system-admin管理者専用の操作を、管理者だけに限定
生存確認エンドポイント何を確かめるか
/api/healthサービスが起動して応答できるか(生存確認)
/api/health/dbデータベースに繋がっているか
/api/health/readyリクエストを受け付ける準備が整ったか(DB + 認証の初期化)

API の仕様も自動で揃えています: 業務 API は Hono という軽量な土台の上に、入力チェック(Zod)と API 仕様書(OpenAPI)の自動生成を組み合わせています。各 API を実装すると、その入力・出力の仕様書が自動的に出来上がるため、画面側との認識ずれを防げます。

正直な注記: 現時点では、この 4 層の骨格・共通処理・生存確認までが整い、本番で /health が応答する段階です。各業務の段取り役(UseCase)の中身 ── ファイル一覧や共有リンク発行といった処理そのもの ── は、この土台の上に今後の開発で実装していきます。骨格を先に固めることで、機能追加のたびに設計が揺らぐのを防いでいます。