📚 参考書籍
※この記事は書籍の一部をベースに再構成しています。もう少し踏み込んだ内容(設計や具体例)は書籍の中でまとめているので、気になる方はそちらもどうぞ。
「ゼロから触ってわかった!Codex - AIエージェント時代のソフトウェア設計」
本書は、AIエージェントと共に開発する時代において、エンジニアが思考停止せず、主体的に価値を発揮し続けるための指針を提示します。
ツールの使い方ではなく、これからの開発の本質を理解したいすべてのエンジニアへ。
https://amzn.to/4o0repH
####『ゼロから触ってわかった!AI Agent Observability入門― MLflow・Databricksで実践するAIエージェントの評価・監視・安全性・説明可能性』
本書は、AI Agentを「作って動かす」だけでなく、その品質をどう観測し、どう評価し、どう守り、どう説明可能にするかを体系的に学ぶための入門書です。
https://link.amazon/B04VaTlR3
⚡Codex実践入門⚡ Design Docからバックエンドを自動生成する7ステップ:Repository PatternとAPI設計の基本
Codexを使ってバックエンドを生成する際、重要なのは単にコードを書かせることではありません。
前節で作成したDesign Docをもとに、設計の意図を崩さず、段階的にコードへ変換することが重要です。
今回は、型定義からデータ層、Repository、API、認証までの生成手順を整理します。
1. バックエンド生成の基本戦略
バックエンドを一度にすべて生成すると、責務の混在や型の不一致が起きやすくなります。
そこで、次の3つを意識します。
- コンテキスト循環:前の生成結果を次の処理へ引き継ぐ
- Repository Pattern:業務ロジックとDB操作を分離する
- Boilerplate:共通コードを先に定義する
Repository Patternとは、データの取得・保存を専用の窓口にまとめる設計手法です。
Boilerplateとは、エラー処理やログ出力など、繰り返し利用する共通コードを指します。
共通ルールを先に固定し、責務ごとに生成することが基本です。
2. Step1:型と共通ルールを定義する
最初に、API全体で利用する型を決めます。
例えば、共通レスポンス型を定義します。
export type ApiResponse<T> = {
data?: T;
error?: {
code: string;
message: string;
};
};
この段階で生成するものは次のとおりです。
- types.ts
- 共通エラー定義
- レスポンス形式
- 命名規則
型の基準を統一することで、後続コードの不整合を減らせます。
3. Step2:Prisma Schemaを生成する
次に、データベースの設計図となるPrisma Schemaを生成します。
model Task {
id String @id @default(uuid())
userId String
title String
description String?
status String @default("todo")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
Prisma Schemaでは、テーブル、カラム、型、制約などを定義します。
2026年現在のPrisma ORMでも、@default(uuid())や@updatedAtによる値の生成・更新が利用できます。
重要なのは、生成したSchemaを保存し、次のステップで参照することです。
4. Step3:ドメインエンティティを生成する
Prisma Schemaを参照し、業務上の型を定義します。
export type TaskStatus = "todo" | "done";
export interface Task {
id: string;
userId: string;
title: string;
description?: string;
status: TaskStatus;
createdAt: string;
updatedAt: string;
}
ここでは、DBの型をそのまま使うのではなく、業務上の制約を表現します。
例えば、statusを単なるstringではなく、"todo" | "done"に制限します。
5. Step3.5:Repository Interfaceを先に定義する
Clean Architectureで重要なのが、実装より先にInterfaceを定義することです。
export interface TaskRepository {
create(task: Task): Promise<Task>;
findByUser(userId: string): Promise<Task[]>;
update(task: Task): Promise<Task>;
delete(taskId: string): Promise<void>;
}
この段階では、DB操作の具体的な実装は作成しません。
先に操作の契約を定義することで、
- 業務ロジックとDBを分離できる
- テスト用Mockへ差し替えられる
- DB変更の影響を抑えられる
というメリットがあります。
6. Step4〜6:業務ロジックからAPIまで生成する
次に、以下の順番で生成します。
Step4:UseCase
CreateTaskでは、
- 入力値を受け取る
- titleを検証する
- statusをtodoで初期化する
- Repository経由で保存する
という処理を定義します。
UseCaseからPrismaを直接呼び出さないことが重要です。
Step5:Repository実装
ここで初めてPrismaを利用します。
PrismaTaskRepositoryを実装し、TaskRepositoryの契約を満たします。
DBのDateTime型とドメインのstring型など、型の変換もここで扱います。
Step6:APIルート
FastifyでPOST /tasksを実装します。
- JWTからユーザーIDを取得
- リクエストを検証
- CreateTaskUseCaseを呼ぶ
- HTTP 201を返す
Controllerに直接DB操作を書かないことが重要です。
7. Step7:認証とバリデーションを組み込む
最後に、非機能要件を反映します。
- Zodによる入力バリデーション
- bcryptによるパスワードハッシュ化
- JWTの署名・有効期限検証
- ログインAPIへのRate Limit
- 他ユーザーのTaskへのアクセス防止
Fastifyでは標準でJSON SchemaとAjvによる検証も利用できます。
Zodを採用する場合は、対応するValidator設定を行います。
認証だけでなく、ユーザー単位の認可も設計することが重要です。
8. コンテキスト循環で設計の一貫性を保つ
バックエンド生成では、前のステップで決めた設計を次へ引き継ぎます。
2026年現在、CodexではAGENTS.mdにプロジェクト固有のルールを記述できます。
- 設計方針
- コーディング規約
- Repositoryの依存ルール
- テスト基準
を保存することで、生成時の参照情報として利用できます。
生成後は必ず、
- Design Docとの型の一致
- Repository経由のDB操作
- Controllerの責務
- 認証・認可の漏れ
- テスト結果
を確認します。
まとめると
バックエンド生成の本質は、AIに大量のコードを書かせることではありません。
- 型を先に決める
- Schemaを生成して引き継ぐ
- Repository Interfaceで境界を固定する
- UseCaseとDB操作を分離する
- APIとセキュリティを組み込む
- 小さく生成し、テストとレビューを繰り返す
「設計 → 分割生成 → 検証 → 修正」
このサイクルを維持することで、Codexを設計意図に沿った開発支援へ活用できます。
