DevToolBox無料
ブログ

REST API設計ベストプラクティス:完全ガイド

12分by DevToolBox

優れたREST APIの設計はJSONを返すだけではありません。適切に設計されたAPIは予測可能、一貫性があり、安全で使いやすいものです。このガイドではREST API設計のベストプラクティスを解説します。

1. リソースURIには名詞を使う

REST APIはリソースをモデル化します。アクションではありません。

# Good - nouns representing resources
GET    /api/v1/users          # list users
GET    /api/v1/users/123      # get user 123
POST   /api/v1/users          # create a user
PUT    /api/v1/users/123      # replace user 123
PATCH  /api/v1/users/123      # partially update user 123
DELETE /api/v1/users/123      # delete user 123

# Bad - verbs describing actions
GET    /api/v1/getUsers
POST   /api/v1/createUser
POST   /api/v1/deleteUser/123
GET    /api/v1/getUserById?id=123
# Nested resources (one level deep)
GET    /api/v1/users/123/orders       # orders for user 123
GET    /api/v1/users/123/orders/456   # order 456 for user 123
POST   /api/v1/users/123/orders       # create order for user 123

# For actions that don't map to CRUD, use sub-resources
POST   /api/v1/users/123/activate     # activate user (action)
POST   /api/v1/orders/456/cancel      # cancel order (action)
POST   /api/v1/emails/789/resend      # resend email

2. HTTPメソッドを正しく使う

各HTTPメソッドには特定のセマンティクスがあります。

MethodPurposeIdempotentRequest Body
GETRead a resourceYesNo
POSTCreate a resourceNoYes
PUTFull replacementYesYes
PATCHPartial updateNo*Yes
DELETERemove a resourceYesNo

3. 複数形のリソース名を使う

コレクションには常に複数形の名詞を使用します。

# Good - consistent plural nouns
/api/v1/users
/api/v1/users/123
/api/v1/products
/api/v1/products/456/reviews

# Bad - mixing singular and plural
/api/v1/user          # singular
/api/v1/user/123
/api/v1/productList   # avoid "list" suffix

4. HTTPステータスコードを正しく使う

ステータスコードはクライアントに何が起きたかを伝えます。

CodeWhen to Use
200 OKSuccessful GET, PUT, PATCH, or DELETE
201 CreatedSuccessful POST that creates a resource
204 No ContentSuccessful DELETE with no response body
400 Bad RequestMalformed request syntax or invalid data
401 UnauthorizedMissing or invalid authentication
403 ForbiddenAuthenticated but not authorized
404 Not FoundResource does not exist
409 ConflictConflicting state (e.g., duplicate email)
422 UnprocessableValidation errors in request body
429 Too Many RequestsRate limit exceeded
500 Internal ErrorUnexpected server error

5. APIをバージョニングする

APIバージョニングは破壊的変更時に既存のコンシューマーを保護します。

# Strategy 1: URI versioning (most common)
GET /api/v1/users
GET /api/v2/users

# Strategy 2: Header versioning
GET /api/users
Accept: application/vnd.myapi.v2+json

# Strategy 3: Query parameter versioning
GET /api/users?version=2
StrategyProsCons
URI pathSimple, visible, cacheableURI pollution
HeaderClean URIsHarder to test, less visible
Query paramEasy to addCache-unfriendly, easy to forget

6. ページネーション、フィルタリング、ソート

コレクションを返すすべてのエンドポイントはページネーションをサポートすべきです。

# Offset-based pagination (simplest)
GET /api/v1/users?page=2&limit=25
GET /api/v1/users?offset=25&limit=25

# Cursor-based pagination (better for large datasets)
GET /api/v1/users?cursor=eyJpZCI6MTAwfQ&limit=25

# Response with pagination metadata
{
  "data": [...],
  "pagination": {
    "total": 1250,
    "page": 2,
    "limit": 25,
    "totalPages": 50,
    "hasNext": true,
    "hasPrev": true
  }
}

# Filtering and sorting
GET /api/v1/products?category=electronics&minPrice=100&maxPrice=500
GET /api/v1/products?sort=price&order=asc
GET /api/v1/products?sort=-created_at  # prefix with - for descending
GET /api/v1/users?fields=id,name,email  # sparse fieldsets

7. エラーレスポンスフォーマット

一貫したエラーフォーマットはクライアントのプログラム的なエラー処理を助けます。

// Consistent error response format
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": [
      {
        "field": "email",
        "message": "Must be a valid email address",
        "value": "not-an-email"
      },
      {
        "field": "age",
        "message": "Must be at least 18",
        "value": 15
      }
    ],
    "requestId": "req_abc123",
    "timestamp": "2026-01-15T10:30:00Z",
    "docs": "https://api.example.com/docs/errors#VALIDATION_ERROR"
  }
}

// Simple error (non-validation)
{
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "message": "User with id 999 not found",
    "requestId": "req_def456"
  }
}

8. 認証とセキュリティ

APIセキュリティは妥協できません。

# Bearer token authentication (JWT)
GET /api/v1/users
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...

# API key authentication
GET /api/v1/users
X-API-Key: sk_live_abc123def456

# OAuth 2.0 token request
POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&scope=read:users write:users
  • Always use HTTPS in production
  • Never put secrets in query parameters (they appear in server logs)
  • Use short-lived access tokens (15-60 min) with refresh tokens
  • Implement CORS properly for browser-based clients
  • Validate and sanitize all input to prevent injection attacks
  • Use rate limiting to prevent brute-force attacks

9. レート制限

レート制限はAPIを悪用から保護します。

# Rate limit response headers (standard)
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000        # max requests per window
X-RateLimit-Remaining: 742     # requests remaining
X-RateLimit-Reset: 1706810400  # Unix timestamp when limit resets
Retry-After: 60                # seconds until next request (on 429)

# Rate limit exceeded response
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 60

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests. Limit: 1000/hour",
    "retryAfter": 60
  }
}

10. HATEOASとリンク

HATEOASはAPIに発見可能性を追加します。

// HATEOAS response example
{
  "id": 123,
  "name": "John Doe",
  "email": "john@example.com",
  "status": "active",
  "_links": {
    "self": { "href": "/api/v1/users/123" },
    "orders": { "href": "/api/v1/users/123/orders" },
    "deactivate": {
      "href": "/api/v1/users/123/deactivate",
      "method": "POST"
    }
  }
}

// Paginated collection with HATEOAS links
{
  "data": [...],
  "_links": {
    "self": { "href": "/api/v1/users?page=2&limit=25" },
    "first": { "href": "/api/v1/users?page=1&limit=25" },
    "prev": { "href": "/api/v1/users?page=1&limit=25" },
    "next": { "href": "/api/v1/users?page=3&limit=25" },
    "last": { "href": "/api/v1/users?page=50&limit=25" }
  }
}

よくある質問

更新にはPUTかPATCHか?

PUTは完全な置換、PATCHは部分更新に使用します。

URIは小文字にすべき?

はい、小文字のkebab-caseを使用してください。

ネストされたリソースの扱い方は?

ネストは1レベルに制限します。

最適な認証方法は?

ユーザー向けアプリにはOAuth 2.0とJWTを使用します。

GraphQLかRESTか?

RESTはシンプルでキャッシュが優れています。GraphQLは複雑なデータ要件に適しています。

TL;DR

  • Use nouns (not verbs) for resource URIs
  • Use the correct HTTP method for each operation
  • Always use plural resource names
  • Return appropriate HTTP status codes
  • Version your API from day one (URI path is simplest)
  • Support pagination, filtering, and sorting for collections
  • Use a consistent error response format
  • Always use HTTPS and proper authentication
  • Implement rate limiting with standard headers
  • Consider HATEOAS for API discoverability

これらのベストプラクティスを最初から守ることで、リファクタリングの時間を節約できます。

𝕏 Twitterin LinkedIn
この記事は役に立ちましたか?

最新情報を受け取る

毎週の開発ヒントと新ツール情報。

スパムなし。いつでも解除可能。

Try These Related Tools

{ }JSON Formatter4xxHTTP Status Code ReferenceJWTJWT Decoder

Related Articles

REST API ベストプラクティス:2026年完全ガイド

REST API設計のベストプラクティス:命名規則、エラーハンドリング、認証、ページネーション、セキュリティを解説。

HTTP ステータスコード:開発者のための完全リファレンスガイド

完全な HTTP ステータスコードリファレンス:1xx〜5xx の実用的解説、API ベストプラクティス、デバッグのコツ。

API認証:OAuth 2.0 vs JWT vs APIキー

API認証方式を比較:OAuth 2.0、JWT Bearerトークン、APIキー。各方式の使い分け、セキュリティトレードオフ、実装パターン。