# 3.6 レスポンス設計のベストプラクティス(Django REST Framework 編)
レスポンス設計のベストプラクティス(Django REST Framework 編)
前回の記事ではパフォーマンス改善と N+1 対策について紹介した。
今回は レスポンス設計のベストプラクティス をテーマにまとめる。
API のレスポンスはフロントエンドが直接扱う部分。
一貫性がなく使いにくい設計だと、結局フロント側の複雑さが増してしまう。
ここでは業務システムで実践しているポイントを整理する。
1. id は必須フィールド
どんな API でも id を返す ことを徹底する。
一覧でも詳細でも、更新やリンクに必要になるため。
{
"id": 1,
"customer_name": "株式会社テスト"
}
2. 一覧と詳細で返却項目を分ける
一覧 API は軽量に、詳細 API は情報を豊富に。
一覧 API(軽量)
[
{ "id": 1, "customer_name": "株式会社テスト", "total_amount": 50000 },
{ "id": 2, "customer_name": "サンプル商事", "total_amount": 120000 }
]
詳細 API(リッチ)
{
"id": 1,
"customer_name": "株式会社テスト",
"total_amount": 50000,
"created_at": "2024-04-01T10:00:00Z",
"items": [
{ "id": 101, "product_name": "商品A", "quantity": 2, "price": 10000 },
{ "id": 102, "product_name": "商品B", "quantity": 1, "price": 30000 }
]
}
Serializer を分けて実装するのが一般的。
3. 表示用フィールドを追加する
金額や日付など、フロントでフォーマットしにくいデータは「表示用フィールド」を追加して返すと便利。
class OrderSerializer(serializers.ModelSerializer):
total_amount_display = serializers.SerializerMethodField()
created_at_display = serializers.SerializerMethodField()
class Meta:
model = Order
fields = ["id", "customer_name", "total_amount", "total_amount_display", "created_at", "created_at_display"]
def get_total_amount_display(self, obj):
return f"¥{obj.total_amount:,}"
def get_created_at_display(self, obj):
return obj.created_at.strftime("%Y/%m/%d %H:%M")
レスポンス例:
{
"id": 1,
"customer_name": "株式会社テスト",
"total_amount": 50000,
"total_amount_display": "¥50,000",
"created_at": "2024-04-01T10:00:00Z",
"created_at_display": "2024/04/01 19:00"
}
4. ネスト構造の扱いを整理する
関連データをどう返すかは API 設計の肝。
- 一覧 API → 関連データは ID のみにする(軽量化のため)
- 詳細 API → ネストしたオブジェクトで返す(ユーザーが画面で必要とする情報をまとめる)
例: 一覧 API
{ "id": 1, "customer_id": 10, "customer_name": "株式会社テスト" }
例: 詳細 API
{
"id": 1,
"customer": {
"id": 10,
"name": "株式会社テスト",
"address": "東京都千代田区1-1-1"
}
}
5. ステータス表現の工夫
数値コードだけでなく、フロント表示用のラベルも一緒に返す。
{
"status": "approved",
"status_display": "承認済み"
}
こうすることで、フロントは翻訳辞書を持たなくてもそのまま表示できる。
6. 一貫性を保つルールを決める
-
命名規則
- スネークケースで統一 (
customer_name,total_amount)
- スネークケースで統一 (
-
日時は ISO 8601
"2024-04-01T10:00:00Z"
-
金額は数値で返す(文字列にしない)
AI活用の観点
レスポンス設計も AI にサポートさせやすい領域。
ただし「おまかせ」だけでは意図通りにならないことが多いので、工夫が必要。
-
まずはおまかせで雛形を生成
例えば「DRF で一覧と詳細でレスポンスを分ける実装例を」と依頼すれば、
Serializer を分けた基本形をすぐに出してくれる。 -
既存レスポンスを例示して整形を依頼
「この JSON をベースに、status にラベルを追加して」と伝えると、
status_displayを追加した Serializer を提案してくれる。 -
命名規則やフォーマットを守らせる
AI はcamelCaseとsnake_caseを混在させることもある。
「すべて snake_case で」と明示することで一貫性を担保できる。 -
表示用フィールドの追加は AI に任せやすい
金額フォーマットや日付整形などは「display 用フィールドを追加して」と言えば即座にコードが生成される。
ただし「どのフィールドを追加するか」の判断は人間側の設計が必要。 -
ネスト構造の深さは人間が設計する
AI に任せると「詳細 API でも ID のみ」「一覧 API でもフルネスト」など極端な設計になることがある。
→ 一覧=軽量 / 詳細=リッチ というルールを与えてから生成させるのが安全。
まとめ
レスポンス設計のベストプラクティス:
-
idは必須 - 一覧は軽量、詳細はリッチ
- 表示用フィールドを追加して UX を改善
- ネスト構造は一覧と詳細で分ける
- ステータスはコードとラベルを両方返す
- 命名・日時・数値のルールを統一する
加えて、AI 活用では 「最初はおまかせ → 修正依頼で調整」 という流れを取ると効率的。
ルールを先に決めて共有し、その基準で AI が生成したコードを整合させるのが実務的な使い方になる。
次回は 認証・権限まわりの設計(DRF + Vue 編) を取り上げる予定。
Discussion