章: 第3章: RESTful API設計
APIに制限なし、それは「やり放題」です
認証なしのAPIエンドポイントは、悪意のある大量リクエストや誤ったループ処理によって、サーバーリソースが枯渇する危険があります。結果として、全ユーザーへのサービス品質が低下します。
レート制限を設けることで、1ユーザーあたりのリクエスト数を制御し、APIの安定稼働を守ることができます。
レート制限の実装
<?php
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
Route::middleware(['auth:sanctum', 'throttle:api'])->group(function () {
Route::get('/posts', [PostController::class, 'index']);
});
制限なし vs レート制限あり
| 観点 | 制限なし | レート制限あり |
| DoS耐性 | 脆弱 | リクエスト数で自動遮断 |
| ユーザーの公平性 | 一部が大量消費可能 | 全ユーザーに均等な割当 |
| コスト管理 | 予測不能 | リクエスト数で制御可能 |
| エラー応答 | なし | 429 Too Many Requests |
チェックポイント:
$request->user()?->id ?: $request->ip()は認証済みユーザーはIDで、未認証ユーザーはIPで制限します。認証済みユーザーには緩い制限、未認証ユーザーには厳しい制限とする設計も一般的です。
複数の制限ルールを設定する
<?php
RateLimiter::for('api', function (Request $request) {
// 未認証ユーザー: 1分10回
if (!$request->user()) {
return Limit::perMinute(10)->by($request->ip());
}
// 管理者: 無制限
if ($request->user()->isAdmin()) {
return Limit::none();
}
// 一般ユーザー: 1分60回
return Limit::perMinute(60)->by($request->user()->id);
});
チェックポイント: レート制限を超えた場合は429ステータスと
Retry-Afterヘッダが自動で返ります。フロントエンドはこのヘッダを見て「X秒後に再試行」のUIを実装できます。
まとめ & 次のステップ
RateLimiter::for()でユーザーごと・IPごとのリクエスト制限を設定できるthrottle:apiミドルウェアをルートグループに適用するだけで有効になる- ユーザー種別ごとに異なる制限ルールを設定して柔軟に管理する
次回はAPIバージョニングを学びます。既存クライアントを壊さずにAPIを進化させる、URLベースのバージョン管理方法です。