コンテンツにスキップ

API 設計初心者がレビューで学んだ REST API 設計の 3 つのポイント

チェック

  • [ ] 本文を確認した
  • [ ] 概要を確認した
  • [ ] タグを確認した
  • [ ] inbox/ 直下へ移行した

概要

REST API 設計を初めて経験した筆者が、レビューを通じて学んだ3つのポイントをまとめた記事。 レスポンスに利用者へ不要な値を含めないこと、API path はリソース階層を意識して設計すること、レスポンスタイムを意識して N+1 や外部 API 呼び出し回数を避けることが中心。 API 利用者の視点、セキュリティ、将来の変更容易性、パフォーマンスを意識する入門メモとして使える。

本文

記事は、入社2年目のアプリケーションエンジニアが、初めて REST API 設計を経験して学んだことをまとめたもの。 CI/CD pipeline、REST API 設計、frontend/backend 開発などを経験した中で、とくに API 設計はレビューからの学びが多かったという背景で書かれている。

1. レスポンスに不要な値を含めない

API 設計では response body も重要。 例として、ユーザー情報を持つ users table がある。

user_id
name
email
created_date
deleted_date
role

一般ユーザーが自分のアカウント情報を取得する API を考える。 悪い例では、次のように table の項目をほぼそのまま返してしまう。

{
  "id": 1,
  "name": "野村太郎",
  "email": "nomura@example.com",
  "created_date": "2026-03-01",
  "deleted_date": null,
  "role": "USER"
}

この response には問題がある。 deleted_date は一般ユーザーにとって不要。 role は管理者向けの情報で、一般ユーザーに見せるべきでない可能性がある。

API 利用者が本当に必要な値だけを返せているか、という視点が必要になる。 不要な値を返すと、セキュリティリスクになるだけでなく、利用者がそのフィールドに依存し、将来の仕様変更が難しくなる。

一般ユーザー向けと管理者向けで response が違うなら、endpoint の責務を分ける。

一般ユーザー向け:

GET /api/v1/users/{id}
{
  "id": 1,
  "name": "野村太郎",
  "email": "nomura@example.com",
  "created_date": "2026-03-01"
}

管理者向け:

GET /api/v1/admin/users/{id}
{
  "id": 1,
  "name": "野村太郎",
  "email": "nomura@example.com",
  "created_date": "2026-03-01",
  "deleted_date": null,
  "role": "USER"
}

必要最小限の情報だけを返すことで、利用者にとって分かりやすく、セキュリティリスクも小さい API になる。

2. パスはリソースの階層構造を意識する

次のポイントは API path。 たとえば、あるカテゴリに属する本一覧を取得する API を考える。

リソースを順に考えると、まずカテゴリがある。

/api/v1/categories

カテゴリ ID で絞る。

/api/v1/categories/{category_id}

そのカテゴリに属する books を取得する。

/api/v1/categories/{category_id}/books

このように、親子関係を path に反映すると、リソース構造が読み取りやすい。

悪い例は次のような path。

/api/v1/categories/books/{category_id}

実際の ID が入ったとき、1 が category に対する ID なのか book に対する ID なのか分かりにくい。

/api/v1/categories/books/1

リソース階層が path から読み取れないと、API 利用者にとって使いづらく、拡張性も落ちる。

ただし、階層を深くしすぎるのもよくない。

/api/v1/categories/{category_id}/books/{book_id}/reviews/{review_id}/comments

特定 book の review comment を取得するのに category を指定する必要がないなら、category 階層は削れる。

/api/v1/books/{book_id}/reviews/{review_id}/comments

path が長くなりすぎる場合は、リソース設計そのものを見直す。 必要なら query parameter を使う選択もある。

3. レスポンスタイムを意識する

API は path と response shape だけでなく、実行時間も設計対象。 画面表示時に API を呼ぶ場合、response が遅いとユーザー体験が悪くなる。

例として、本一覧 API を考える。 book table と category table が分かれている。

book table:

book_id
title
published_date
isbn
category_id

category table:

category_id
category_name

response では本ごとに category_name も返す。

{
  "books": [
    {
      "book_id": 1,
      "title": "Java 入門",
      "category_name": "プログラミング",
      "published_date": "2026-03-01",
      "isbn": "123-4-567-11111-1"
    }
  ]
}

安易な実装では、まず book 一覧を取得し、その後 book ごとに category_id から category を取得する。 この場合、SQL 実行回数は 1 + N になる。 book が3件なら4回で済むが、数百、数千件になると大量の SQL になる。

これは N+1 問題。 データ数が少ない時点では問題が見えにくいが、将来増えると response が遅くなる。

対策として、JOIN を使い SQL 実行回数を減らす。

SELECT
  b.book_id,
  b.title,
  c.category_name,
  b.published_date,
  b.isbn
FROM books b
JOIN categories c ON c.category_id = b.category_id;

同じ考え方は SQL だけでなく外部 API 呼び出しにも当てはまる。 一覧の各要素ごとに外部 API を呼ぶと、件数に比例して遅くなる。 batch API、JOIN 相当の取得、事前集約、cache、非同期処理などで呼び出し回数を抑える。

API 利用者の視点

記事の締めは、API 設計に唯一の正解はないが、API 利用者の視点を持つだけで設計は大きく変わる、というもの。

利用者に不要な情報を返していないか。 path からリソースの関係が読めるか。 将来データが増えても response time が破綻しないか。

この3点は、初心者だけでなく実務でも頻繁にレビュー対象になる。

要点

  • API response は table 構造をそのまま返さず、利用者に必要な値だけ返す。
  • 不要な値はセキュリティリスクや将来の互換性リスクになる。
  • 一般ユーザー向けと管理者向けで情報が違うなら endpoint を分ける。
  • API path はリソースの親子関係を意識して設計する。
  • 階層を深くしすぎる場合はリソース設計や query parameter を検討する。
  • N+1 問題を避け、SQL や外部 API の実行回数を意識する。
  • API 設計では利用者視点、セキュリティ、性能を同時に見る。

タグ

rest-api #api-design #backend #security #performance #n-plus-one