0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Laravelのエラーハンドリングとバリデーションを含んだAPIについて

Last updated at Posted at 2024-09-20

はじめに

この記事はLaravelでAPIを操作する際のエラーハンドリングとバリデーションに関する手順をまとめたメモになります

ルーティングの設定

routes/api.php に、APIのルートを追加することで、基本的なPOSTリクエストを受け取るAPIを設定します。

Route::post('/user', [UserController::class, 'store']);

コントローラーの作成

以下のコマンドでコントローラーを生成することができます

php artisan make:controller UserController

コントローラーに必要なメソッド(例)

UserController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    public function store(Request $request)
    {
        // バリデーション処理
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|min:8',
        ]);

        // 正常処理
        return response()->json(['message' => 'User created successfully']);
    }
}

マスアサインメントの設定

マスアサインメントとは

特定の作業やリソース(人、物、情報など)を一度に多くの対象に割り当てることを指します。
例えば、学校のイベントで多くの生徒が役割を持つ場合、一斉に役割を振り分けることがマスアサインメントです。

Laravelのマスアサインメント

この記事では一度に複数のデータを連想配列としてモデルに渡し、その全てを一括で保存することをマスアサインメントと呼称しております
Laravelではセキュリティのために、マスアサインメントで保存する際には制限が設けられており、この制限によってマスアサインメントが許可されていないフィールドに対して一括でデータを保存しようとすると、システムはマスアサインメントによる不正な操作と判断し、エラーを発生させます

マスアサインメントの例

以下の例では保存処理で 'name', 'email', 'password'を新規保存する際にバリデーションの対象となっていたのでマスアサインメントの設定を実施しています

User.php


<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    // マスアサインメントを許可するフィールドを指定
    protected $fillable = ['name', 'email', 'password'];
}

バリデーションの方法と概要

バリデーションとは、入力されたデータが正しいかどうかを確認することです。
例えば、ウェブサイトのフォームに情報を入力するときに、その情報が適切かどうかをチェックするために使われます。これにより、間違ったデータや不完全な情報が送信されるのを防ぎます。

バリデーションの例

***controller.php
$validated = $request->validate([
            'name' => 'required|string|max:255',
           
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|min:8',
        ]);
  • name フィールドに対して必須 文字列 最大255文字という3つのルールを適用する場合は上記のように書きます
  • リクエストの中身がrequired, string, max:255 の3つのルールを満たさない場合はエラーを発生させます

メソッドの補足

  • $request->validate()

リクエストから送信されたデータ($request)に対してバリデーションを行います。データが正しくない場合は、自動的にエラーレスポンスが返されます

  • $request

クライアントから送信されたデータを含むオブジェクトです

  • validate()

リクエストのデータがルールに従っているかどうかを検証します

バリデーションの種類について

Laravelで設定できるバリデーションルール以下の通り様々存在します

必須/オプション

  • accepted: フィールドが yes, on, 1, または true であることを確認
  • active_url: フィールドが有効なURLであることを確認
  • after:date : フィールドが指定された日付より後の日付であることを確認
  • after_or_equal:date : フィールドが指定された日付以上であることを確認
  • alpha: フィールドがアルファベットのみであることを確認
  • alpha_dash: アルファベット、数字、ダッシュ、アンダースコアのみであることを確認
  • alpha_num: アルファベットと数字のみであることを確認
  • array: フィールドが配列であることを確認
  • bail: 最初のバリデーションエラーが発生したら、後続のルールをスキップ

数値/長さ

  • between:min,max: 数値、文字列、またはファイルのサイズが指定された範囲内であることを確認
  • boolean: フィールドが true または false であることを確認
  • confirmed: 指定されたフィールド(通常はパスワード)が確認フィールドと一致することを確認
  • date: フィールドが有効な日付であることを確認
  • date_equals:date : 指定された日付と等しいことを確認
  • date_format:format: フィールドが指定されたフォーマットと一致することを確認

ファイル

file: フィールドがアップロードされたファイルであることを確認
image: 画像ファイルであることを確認(jpeg, png, bmp, gif, svg, webp)
mimes:types: ファイルが指定されたMIMEタイプ(例: jpeg, png)であることを確認
mimetypes:types: ファイルが指定されたMIMEタイプ(例: image/jpeg, video/mp4)であることを確認

比較

  • different:field: 他のフィールドと異なることを確認
  • digits:value: 指定された桁数であることを確認
  • digits_between:min,max: 指定された範囲内の桁数であることを確認
  • email: フィールドが有効なメールアドレス形式であることを確認
  • exists:table,column: データベースの指定されたテーブルとカラムに値が存在することを確認

ユニーク性

  • unique:table,column: 指定されたテーブルのカラムにおいて値がユニークであることを確認

サイズ/範囲

  • max:value : フィールドが指定された最大サイズ(文字数やファイルサイズなど)以下であることを確認
  • min:value : フィールドが指定された最小サイズ以上であることを確認

その他

  • nullable: フィールドが空でも許容することを指定
  • regex:pattern: フィールドが指定された正規表現パターンに一致することを確認
  • required: フィールドが必須であることを確認
  • required_if:anotherfield,value: 指定されたフィールドが特定の値の場合に、このフィールドが必須であることを確認
  • required_with:field1,field2,...: 指定された他のフィールドが存在する場合、このフィールドが必須であることを確認

Laravelのエラーハンドリング

バリデーションなどによってエラーが発生した場合にエラーを適切に処理するための仕組みをエラーハンドリングと呼びます。
エラーハンドリングをすることで、ユーザーに対して理解しやすいエラーメッセージを表示したり、ログにエラー情報を記録したりすることができます。

エラーハンドリングの流れ

バリデーションによるエラーなどが発生した場合、以下の流れでエラー処理が実行されます

① エラーオブジェクトがスローされる

  • 「スロー」するとは「投げる」という意味合いで、例えばバリデーションエラーの場合が発生した場合はcontrollerValidationExceptionというエラーオブジェクトが生成されます。そのオブジェクトはLaravelのフレームワークによって自動的にキャッチされ、Handler.phpに渡されます
  • ValidationExceptionはバリデーションルールに従わない入力があった場合にcontrollerで作成されるエラー情報が格納されたオブジェクトです
  • ログインをしていないユーザーがログイン後のページを見ようとした時に発生するAuthorizationExceptionなどエラーの種類によってエラーオブジェクトは複数存在し、Handler.phpへスローされます

② Handler.phpの呼び出し

Handler.phpではエラーが発生した際の処理全般が定義されており、生成されたエラーオブジェクトをIF文などで判断し実行される処理を区別できます。

③ renderメソッドの実行

Handler.phpにはrenderメソッドが存在し、スローされたエラーオブジェクトが引数として渡されます。このメソッド内では、エラーオブジェクトが$exceptionという変数に代入され、if文などを使ってエラーオブジェクトの種類に応じた特定の処理(例えば、エラーページの表示や適切なレスポンスの生成)を行うことができます。

Handler.phpについて

Laravelのアプリケーション内でエラーや例外が発生した場合、上述の通りapp/Exceptions/Handler.php が呼び出されその情報は $exception という変数に格納されます

Handler.php
namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
    // エラーを記録する
    public function report(Throwable $exception)
    {
        // エラーの情報を記録します
        parent::report($exception);
    }

    // エラーメッセージを返す
    public function render($request, Throwable $exception)
    {
        // 特定のエラーに対してカスタムメッセージを返す
        if ($exception instanceof CustomException) {
            return response()->json(['error' => 'カスタムエラーメッセージ'], 400);
        }

        // デフォルトのエラーメッセージを返す
        return parent::render($request, $exception);
    }
}

  • parent::report($exception);
    Laravelがエラーや問題が起こったときに、そのエラーの情報を自動で記録してくれる機能を呼び出すためのものです。削除した場合はLaravelの標準のエラーログ(storage/logs/laravel.log に保存)は行われません。

  • if ($exception instanceof CustomException)
    $exception という変数に入っているエラーが、CustomException という特定のエラー(例外)であるかどうかを確認する」ためのコードです。

  • return response()->json()
    response() は、Laravelのヘルパー関数で、HTTPレスポンス(サーバーからクライアントへの応答)を作成するためのものです。json() は、レスポンスをJSON形式に変換します。APIでは、データをやり取りするときにJSON形式がよく使われます

  • json(['error' => 'カスタムエラーメッセージ'], 400)
    'error' というキーに対して 'カスタムエラーメッセージ' という内容が設定されています。このメッセージはGoogle Chromeの検証ツールからレスポンスなどで確認できます。同時にHTTPステータスコード(400)が返されます。HTTPステータスの番号およびメッセージの内容は自由に変更できます

エラーページに誘導させる

エラーが発生した際に特定のエラーページへ自動でリダイレクトさせたい場合は、以下のようにエラーページへリダイレクトさせます

Handler.php
public function render($request, Throwable $exception)
{
    // 401エラー(未認証)
    if ($exception instanceof \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException) {
        return redirect('/401'); // 401ページにリダイレクト
    }

    // 403エラー(アクセス拒否)
    if ($exception instanceof \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException) {
        return redirect('/403'); // 403ページにリダイレクト
    }

    // 404エラー(ページが見つからない)
    if ($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) {
        return redirect('/404'); // 404ページにリダイレクト
    }

    // 500エラー(サーバー内部のエラー)
    if ($exception instanceof \Symfony\Component\HttpKernel\Exception\HttpException) {
        return redirect('/500'); // 500ページにリダイレクト
    }

    // その他のエラーについては、標準のエラーメッセージおよびページを表示
    return parent::render($request, $exception);
}

HTTPステータスについての補足(エラーコード)

  • 401エラー
    認証が必要なページにアクセスした際にリダイレクトされます
  • 403エラー
    アクセスが拒否された場合、403エラーページにリダイレクトされます
  • 404エラー
    指定されたページが見つからない場合、404エラーページにリダイレクトされます
  • 500エラー
    サーバーで何らかの問題が発生した場合、500エラーページにリダイレクトされます
  • その他のエラー
    上記の条件に該当しないエラーが発生した場合、Laravelのデフォルトのエラーハンドリングが行われます。
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?