APIはプロダクトである
世界最高のAPI — Stripe、Twilio、GitHub — は、しばしばその企業自身のユーザーインターフェースよりも優れたプロダクトと評されます。これは偶然ではありません。これらの企業は、UIと同じ配慮を開発者体験に注ぎ、APIをファーストクラスのプロダクトとして扱っています。
このガイドでは、本番グレードのAPIとそれ以外を分けるエンジニアリングの実践を扱います。
API設計の原則
REST vs GraphQL vs gRPC
ユースケースに合ったプロトコルを選びましょう:
| プロトコル | 最適な用途 | 避けるべき場合 |
|---|---|---|
| REST | 標準的なCRUD、公開API | 複雑なクエリ、リアルタイム |
| GraphQL | 柔軟なクエリ、モバイルクライアント | 単純な操作、ファイルアップロード |
| gRPC | 内部サービス、高パフォーマンス | 公開API、ブラウザクライアント |
| WebSocket | リアルタイム、双方向 | リクエスト・レスポンス型パターン |
命名と構造
優れたAPI設計は退屈なものです。確立された規則に従うことで、開発者はドキュメントを読まなくても動作を予測できます。
✅ 良いREST API設計:
GET /api/v1/users # ユーザー一覧
POST /api/v1/users # ユーザー作成
GET /api/v1/users/{id} # ユーザー取得
PUT /api/v1/users/{id} # ユーザー置換
PATCH /api/v1/users/{id} # ユーザー更新
DELETE /api/v1/users/{id} # ユーザー削除
GET /api/v1/users/{id}/orders # ユーザーの注文を取得
❌ よくある間違い:
GET /getUser?userId=123
POST /api/createNewUser
GET /api/fetchUserOrders/{userId}
認証と認可
JWTのベストプラクティス
import jwt from 'jsonwebtoken'; // ✅ 短命なアクセストークン + リフレッシュトークン const ACCESS_TOKEN_EXPIRY = '15m'; const REFRESH_TOKEN_EXPIRY = '7d'; function generateTokenPair(userId: string) { const accessToken = jwt.sign( { sub: userId, type: 'access' }, process.env.JWT_SECRET!, { expiresIn: ACCESS_TOKEN_EXPIRY } ); const refreshToken = jwt.sign( { sub: userId, type: 'refresh', jti: crypto.randomUUID() }, process.env.REFRESH_SECRET!, { expiresIn: REFRESH_TOKEN_EXPIRY } ); return { accessToken, refreshToken }; }
レート制限
レート制限はAPIを悪用から保護し、公平な利用を保証します。複数のレベルで実装しましょう:
- IPレベルの制限: DoS攻撃を防ぐ
- ユーザーレベルの制限: 公平な利用を強制する
- エンドポイントレベルの制限: コストの高い操作にはより低い制限を設ける
import { Ratelimit } from '@upstash/ratelimit'; import { Redis } from '@upstash/redis'; const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(100, '1 m'), // 1分あたり100リクエスト analytics: true, }); export async function apiMiddleware(req: Request) { const identifier = getClientIdentifier(req); const { success, limit, remaining, reset } = await ratelimit.limit(identifier); if (!success) { return new Response('Too Many Requests', { status: 429, headers: { 'X-RateLimit-Limit': limit.toString(), 'X-RateLimit-Remaining': remaining.toString(), 'X-RateLimit-Reset': new Date(reset).toISOString(), 'Retry-After': Math.ceil((reset - Date.now()) / 1000).toString(), }, }); } }
エラーハンドリング
一貫性があり有益なエラーレスポンスは、優れたAPIの証です。
{ "error": { "code": "VALIDATION_ERROR", "message": "The request body is invalid", "details": [ { "field": "email", "message": "Must be a valid email address", "value": "not-an-email" } ], "requestId": "req_abc123", "docs": "https://api.eryon.ai/docs/errors/VALIDATION_ERROR" } }
APIバージョニング
利用者を壊さないでください。初日からAPIのバージョン管理をしましょう。
戦略:URLパスバージョニング(最もシンプルで互換性が高い)
/api/v1/users
/api/v2/users
バージョニングルール:
- メジャーバージョン(v1 → v2):破壊的変更
- マイナーバージョン: 後方互換性のある追加
- 廃止ポリシー: バージョンを削除する6か月前に告知する
開発者が信頼し、ビジネスの堀となるAPIは、これらの基盤の上に構築されています。API設計で手を抜くたびに、何千もの稼働中の連携を抱えた状態でそれを修正する際、その10倍のコストがかかります。
Isha Reddy
Frontend Architect at ERYON AI
Expert in cutting-edge technology, AI systems, and enterprise software development.
関連サービス
Web Applications