24
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LaravelでFormRequest使ってJSONをValidateする って、どんな呪文だ?

Posted at

Laravelって、気が付くとcontrollerがひどいことになるよね。MVCの宿命かもしれないけど。
今回はAPIの処理で受け取ったJSONのvalidationをFormRequestを使ってやってみるよ。
下記サイトをバリ参考にしました。ありがとうございます。
Laravelを使ったAPI開発でController内のバリデーションをFormRequestに抽出して幸せになろう

ちなみに環境は下記の通り
Laravel 7.13.0
OS Windows10
開発環境 homestead
DB mysql

1.チェックしたいJSON

こんな感じのデータをチェックするよ。

{		
    "company_id" : "12345"	,
    "company_name" : "corp XXX",
    "branches" : [	
        {"no" : "1", 
         "branch_code" : "0123",
         "branch_name" : "ABC"
        }
        {"no" : "2", 
         "branch_code" : "9876",
         "branch_name" : "XYZ"
        }
    ]	
}

配列の中に更に配列があるパターンだね。
APIでこれをもらってきて、必須チェックとか数字チェックとかするよ。

2.考え方

イメージとして、controllerでJSONを受け取るとき、まさに受け取るところでValidationをかけます。
これは、受け取るときのパラメータの書き方を、通常の(Request $request)から、(《FormRequestの名前》 $request)にして、FormRequestを通ってきたものを使うようにすればよいのです。

contollerの例
public function store (JsonRequest $request)
{
    //普通に処理を書いていく
    //$reqesutはvalidation実行後のものになる

}

では、FormRequestを書いていこう。

3.FormRequestの中身

まずは例によってartisanでrequestを作成するよ。
今回は「JsonRequest」という名前のrequestを作成します。

php artisan make:request JsonRequest

そうすると、/app/Httpの下に「Requests」というフォルダーが作成され、その中に「JsonRequest.php」が作成される。

JsonRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;

class JsonRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return false;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
            ];
    }
}

こんな感じ。

public function authorize()は認証関係のチェックを行う用のfunctionです。
認証なんて何もしないよ!という人はreturnをtrueに変更してください。でないと常にfalseが返ってしまい、いつまでも認証エラーです。

piblic function rules()の中に、validationのルールを書いていきます。
書き方は普通のlaravelのvalidationの書き方と同じです。
公式マニュアルはこちら
今回はこんな風に書いてみました。
companyテーブルは、そういうものがあるつもりで考えてね。

JsonRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;

class JsonRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
            'company_id' => 'exists:company,id',  //comapnyテーブルの存在チェック
            'company_code' => 'numeric',    //数字であること
            'branches.*.no' => ['numeric', 'distinct'],   //数字、かつ重複チェック
            'branches.*.branch_code' => 'numeric',    //数字であること
            ];
    }
}

普通はこれでいいんだけど、FormRequestは基本画面から呼ばれた前提で処理が作られており、エラーが発生したとき画面にエラーメッセージを返そうとします。
今回はAPIで受け取っているので、エラー情報の返却もJSONで返したい。
なので、レスポンスをJSONで返す処理を追加します。

JsonRequest.php

    //public function rulesの後とか、適当なところに追加

    protected function failedValidation(Validator $validator)
    {
        $res = response()->json([
            'status' => 400,
            'errors' => $validator->errors(),
        ],400);
        throw new HttpResponseException($res);
    }

もし独自のチェックをしたいとか、validationでない処理もしたいとか考えているなら、public function withValidatorに$varidator->afterとか追加すれば実現できます。ここでは書かないけど。

ここまで出来たら、最初に書いたようにcontrollerにJsonRequestを追加してください。

JsonController.php
// 必要なところだけ抜粋
//最初にJsonRequestを取り込んでね
use App\Http\Requests\JsonRequest;

//途中省略

    public function store(JsonRequest $request)
    {
     //普通に処理を書く
     //validateはもう実行済み

    }

こうすると、あら不思議。勝手にvalidateされちゃいます。
メッセージの変更の仕方とかは、別の人の記事を探してね。

まずは、めでたしめでたし。

24
12
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
24
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?