1
0

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 1 year has passed since last update.

Laravel 配列のバリデーションを実装してみる

Last updated at Posted at 2021-04-23

こんにちは、JeffTechです。

説明

LaravelでAPIを作成している際に、リクエストの中に配列が混ざっているものを必須バリデーションさせる方法を説明します。
下記のようなリクエストがJSON形式で飛んできたことを想定していきます。

{
	"app": {
		"posts": [
			{
				"post": {
					"id": "3",
					"count": "10"
				}
			}
		]
	}
}

この記事で実現できること

  • 配列のバリデーションを実装することができる

開発環境

  • OS: MacOs
  • PHP: 7.3
  • Larave: 6.2

実装の流れ

  1. Laravelプロジェクトの作成
  2. 日本語化
  3. Controllerの作成&編集
  4. Requestの作成&編集
  5. テスト

実装

Laravelプロジェクトの作成

まずはLaravelをインストールしちゃいます。

$ composer create-project --prefer-dist laravel/laravel api_array_validation '6.*'

日本語化

エラーメッセージを日本語で出力したいので、下記コマンドでresources/lang/jaファイルを作成してください。

$ php -r "copy('https://readouble.com/laravel/6.x/ja/install-ja-lang-files.php', 'install-ja-lang.php');"
$ php -f install-ja-lang.php
$ php -r "unlink('install-ja-lang.php');"

デフォルトでは英語のresources/lang/enファイルが使用されるようになっていますが、config/app.phpで日本語用のファイルを使用するように設定しましょう。

config:app.php
<?php

return [

    ーー省略ーー

    /*
    |--------------------------------------------------------------------------
    | Application Locale Configuration
    |--------------------------------------------------------------------------
    |
    | The application locale determines the default locale that will be used
    | by the translation service provider. You are free to set this value
    | to any of the locales which will be supported by the application.
    |
    */

    'locale' => 'ja',

    ーー省略ーー
]

Controllerの作成&編集

今回使用するコントローラの作成です。

$ php artisan make:controller PostController

$requestを受け取って、バリデーションが通れば成功と出力する簡単なものにします。

app/Http/Controllers/PostController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests\PostRequest;

class PostController extends Controller
{
    public function index(PostRequest $request)
    {
        $request = $request->all();
        dd('成功');
    }
}

Requestの作成&編集

バリデーションを設定するためにフォームリクエストを作成していきます。

$ php artisan make:request PostRequest

バリデーションを実装していきます。

app/Http/Requests/PostRequest.php
<?php

namespace App\Http\Requests;

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

class PostRequest 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 [
            'app.posts' => 'required',
            'app.posts.*.post.id' => 'required|integer',
            'app.posts.*.post.count' => 'required|integer',
        ];
    }

    /**
     * エラーメッセージを出力
     * 
     * @return viod
     */
    protected function failedValidation(Validator $validator)
    {
        $response['errors'] = $validator->errors()->toArray();

        throw new HttpResponseException(
            response()->json($response, 422, [], JSON_UNESCAPED_UNICODE,)
        );
    }

    /**
     * エラーメッセージを変更
     * 
     * @return array
     */
    public function messages()
    {
        return [
            'application.menus.*.menu.id.required' => ':attributeは必ず指定してください。',
            'application.menus.*.menu.count.required' => ':attributeは必ず指定してください。',
        ];
    }

    /**
     * エラー用文言を設定
     * 
     * @return array
     */
    public function attributes()
    {
        return [
            'application.menus.*.menu.id' => 'application.menus.*.menu.id',
            'application.menus.*.menu.count' => 'application.menus.*.menu.count',
        ];
    }
}

これで実装自体は終わりです。
Response::json()の第4引数に、JSON_UNESCAPED_UNICODEを設定すると、unicodeで日本語をエスケープせずにそのまま返してくれます。

'app.posts' => 'required',

で配列自体にバリデーションをかけて、

'app.posts.*.post.id' => 'required|integer',
'app.posts.*.post.count' => 'required|integer',

で各要素にバリデーションをかけていきます。
エラーメッセージを出力する処理やmessagesメソッド、attributesメソッドはトレイトとかで共通化するともっと楽になりそうです。
実装したい場合はこちらを御覧ください。

テスト

今回私はinsomniaを使用してテストを行っていきます。
insomniaって何!って人はPostmanを想像してください。
insomniaめちゃ良いので、よかったらこちらからインストールください。

$ php artisan serveで簡易サーバーを起動して、insomniaにてGETでhttp://127.0.0.1:8000/api/validateを叩いてみると、しっかりと下記のようなエラーメッセージが出力されると思います。

postなしの場合

リクエスト
{
	"app": {
	}
}
レスポンス
{
  "errors": {
    "app.posts": [
      "app.postsは必ず指定してください。"
    ]
  }
}

idとcountなしの場合

リクエスト
{
	"app": {
		"posts": [
			{
				"post": {
				}
			}
		]
	}
}
レスポンス
{
  "errors": {
    "app.posts.0.post.id": [
      "app.posts.0.post.idは必ず指定してください。"
    ],
    "app.posts.0.post.count": [
      "app.posts.0.post.countは必ず指定してください。"
    ]
  }
}

idとcountが文字の場合

リクエスト
{
	"app": {
		"posts": [
			{
				"post": {
					"id": "aaa",
					"count": "aaa"
				}
			}
		]
	}
}
レスポンス
{
  "errors": {
    "app.posts.0.post.id": [
      "app.posts.0.post.idは整数で指定してください。"
    ],
    "app.posts.0.post.count": [
      "app.posts.0.post.countは整数で指定してください。"
    ]
  }
}

正常時

正常な値が送られている時には、コントローラで設定した成功と出力されます。

リクエスト
{
	"app": {
		"posts": [
			{
				"post": {
					"id": "1",
					"count": "10"
				}
			}
		]
	}
}
insomnia出力
"成功"

最後に

少しでも役に立った!という時は、いいねをポチッとして
フォローしてくださると嬉しいです、、、笑

役に立たなかった時は、怒らないでコメント頂けますと幸いです笑

Twitterもやってますので、よかったら見てみてくださいね!
https://twitter.com/jefftechsaku

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?