APIを提供するサーバー側では、リクエストのバリデーションや内部処理の結果に応じて、適切なHTTPステータスコードを返す必要があります。本記事では、PHPを使用したAPIサーバーの構築例と、400系(クライアントエラー)や500系(サーバーエラー)の判定方法について解説します。
1. 基本的なAPIサーバーの構成
PHPでAPIを作成し、400系・500系のエラーを適切に判定・返すコードの例を紹介します。
基本のAPIコード
phpコピーする編集するheader("Content-Type: application/json");
// リクエストメソッドを取得
$method = $_SERVER['REQUEST_METHOD'];
try {
    if ($method === "GET") {
        handleGetRequest();
    } elseif ($method === "POST") {
        handlePostRequest();
    } else {
        throwError(405, "Method Not Allowed");
    }
} catch (Exception $e) {
    throwError(500, "Internal Server Error: " . $e->getMessage());
}
/**
 * GETリクエストの処理
 */
function handleGetRequest()
{
    $users = [
        ["id" => 1, "name" => "John Doe"],
        ["id" => 2, "name" => "Jane Doe"]
    ];
    response(200, ["status" => "success", "data" => $users]);
}
/**
 * POSTリクエストの処理(バリデーションあり)
 */
function handlePostRequest()
{
    $input = json_decode(file_get_contents("php://input"), true);
    if (!isset($input['name']) || empty($input['name'])) {
        throwError(400, "Invalid request. 'name' is required.");
    }
    response(201, ["status" => "success", "message" => "User created"]);
}
/**
 * 正常なレスポンスを返す
 */
function response($statusCode, $data)
{
    http_response_code($statusCode);
    echo json_encode($data);
    exit;
}
/**
 * エラー時のレスポンスを統一
 */
function throwError($statusCode, $message)
{
    http_response_code($statusCode);
    echo json_encode(["status" => "error", "message" => $message]);
    exit;
}
2. 各エラーハンドリングの詳細
400 Bad Request
phpコピーする編集するif (!isset($input['name']) || empty($input['name'])) {
    throwError(400, "Invalid request. 'name' is required.");
}
主な原因
- JSONフォーマットが間違っている
 - 必須パラメータが不足している
 
エラーレスポンス例
jsonコピーする編集する{
    "status": "error",
    "message": "Invalid request. 'name' is required."
}
401 Unauthorized
phpコピーする編集するif (!isset($_SERVER['HTTP_AUTHORIZATION']) || $_SERVER['HTTP_AUTHORIZATION'] !== 'Bearer valid_token') {
    throwError(401, "Unauthorized: Invalid token.");
}
主な原因
- 認証トークンがない
 - 認証トークンが不正
 
エラーレスポンス例
jsonコピーする編集する{
    "status": "error",
    "message": "Unauthorized: Invalid token."
}
403 Forbidden
phpコピーする編集するif ($userRole !== "admin") {
    throwError(403, "Forbidden: You do not have permission.");
}
主な原因
- アクセス権限が不足している
 
エラーレスポンス例
jsonコピーする編集する{
    "status": "error",
    "message": "Forbidden: You do not have permission."
}
404 Not Found
phpコピーする編集するif ($userId !== 1) {
    throwError(404, "User not found.");
}
主な原因
- 指定されたリソースが存在しない
 
エラーレスポンス例
jsonコピーする編集する{
    "status": "error",
    "message": "User not found."
}
405 Method Not Allowed
phpコピーする編集するif ($method !== "GET" && $method !== "POST") {
    throwError(405, "Method Not Allowed");
}
主な原因
GETのみ許可されているAPIにPOSTでリクエストしている
エラーレスポンス例
jsonコピーする編集する{
    "status": "error",
    "message": "Method Not Allowed"
}
3. 500系(サーバーエラー)の処理
500 Internal Server Error
phpコピーする編集するtry {
    throw new Exception("Something went wrong");
} catch (Exception $e) {
    throwError(500, "Internal Server Error: " . $e->getMessage());
}
主な原因
- プログラムのバグ
 - データベース接続エラー
 - メモリ不足
 
エラーレスポンス例
jsonコピーする編集する{
    "status": "error",
    "message": "Internal Server Error: Something went wrong"
}
502 Bad Gateway
phpコピーする編集するif (!$backendApiResponse) {
    throwError(502, "Bad Gateway: Backend API not responding.");
}
主な原因
- リバースプロキシ(Nginx, AWS ALBなど)がバックエンドと通信できない
 
エラーレスポンス例
jsonコピーする編集する{
    "status": "error",
    "message": "Bad Gateway: Backend API not responding."
}
503 Service Unavailable
phpコピーする編集するif ($serverLoad > 90) {
    throwError(503, "Service Unavailable: Server is overloaded.");
}
主な原因
- サーバーが過負荷状態
 
エラーレスポンス例
jsonコピーする編集する{
    "status": "error",
    "message": "Service Unavailable: Server is overloaded."
}
504 Gateway Timeout
phpコピーする編集するif ($apiResponseTime > 30) {
    throwError(504, "Gateway Timeout: API response too slow.");
}
主な原因
- バックエンドAPIのレスポンスが遅すぎる
 
エラーレスポンス例
jsonコピーする編集する{
    "status": "error",
    "message": "Gateway Timeout: API response too slow."
}
4. まとめ
| ステータスコード | エラー内容 | 主な原因 | 
|---|---|---|
| 400 | Bad Request | JSONフォーマットエラー、必須パラメータ不足 | 
| 401 | Unauthorized | APIキー・JWTトークンが無効 | 
| 403 | Forbidden | アクセス権限がない | 
| 404 | Not Found | URL間違い、リソースが存在しない | 
| 405 | Method Not Allowed | HTTPメソッド間違い | 
| 500 | Internal Server Error | サーバーのバグ、DBエラー | 
| 502 | Bad Gateway | リバースプロキシがバックエンドに接続不可 | 
| 503 | Service Unavailable | サーバー過負荷 | 
| 504 | Gateway Timeout | API応答が遅すぎる | 
PHPで適切に400系・500系のエラーハンドリングを行うことで、APIの信頼性を向上させることができます。
エラーハンドリングの実装を適切に行い、スムーズなAPI運用を目指しましょう。
コメントを残す