【Laravel8 api】バリデーションをFormRequestsに書いてみる。エラーはjsonで返す。

Laravel

今回はLaravelのバリデーションをFormRequestに書いてみました。別クラスを作って作成するということですね。

簡単なCRUDを作ってそこでバリデーションをしていこうと思います。

ネットに上がっている記事は結構controllerに書いているものが多かったので別の方法を紹介します!

環境はLaravel8.xを想定しています!

バリデーションをcontrollerとは別に書くことで、cotroller自体がすっきり書くことができるので良いです!!!

それでは行ってみよーー (oノ´3`)ノ ピューーン!!

tableの作成

まずはテーブルを作っていきます。

今回はMemoっていうのを作っていきます。

php artisan make:model Memo -a

上記コマンドを使うことによってControllerやModelやmimgrationファイルとか必要なやつたくさん作ってくれます。

ほんで今回は簡単なテーブルをつくりますー

{app_name}/database/migrations/yyyy_mm_dd_xxxxxx_create_memos_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateMemosTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('memos', function (Blueprint $table) {
            $table->id();

            $table->string('title');
            $table->string('content');

            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('memos');
    }
}
php artisan migrate

ほい、こんな感じでタイトルとコンテンツが入力できるようなやつ作成。

Modelを書く

一応modelも書いていく。

{app_name}/app/Models/Memo.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Memo extends Model
{
    //id以外は好きにinsert/updateができるように指定。(ブラックリスト方式)
    protected $guarded = ['id'];
    use HasFactory;
}

ちなみに$guardedのほかには$fillableというのがありますが、それはホワイトリスト方式で好きにいじれるカラムを指定することができます。

今回は$guardedを使いますね~

カラム追加したときとかも対応しやすいんじゃないかなあと思ってます。

ほんなら先にバリデーション用のクラス作ってみます~

FormRequestの作成

ほい、今回はメモをcreateするという想定でやりましょうか。

createの為のバリデーションを書きますね。

php artisan make:request Memo/StoreMemoRequest

このコマンドでバリデーション用のクラスが作れます!

ほんでいじっていきます~

<?php

{app_name}/app/Http/Requests/Memo/StoreMemoRequest.php

namespace App\Http\Requests\Memo;

use Illuminate\Foundation\Http\FormRequest;

//---------------------------------------
//以下より追加
//---------------------------------------
use Illuminate\contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;

class StoreMemoRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        //ルーティングファイル、もしくはコントローラーで認証処理は行う前提なのでtrueで返す
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */

    //バリデーションルールの指定
    public function rules()
    {
        return [
            'title' => ['required', 'string', 'max:255'], //入力必須、文字列、最大255
            'content' => ['required', 'string', 'max:255'],
        ];
    }

    //validationでエラーがあった時のエラーメッセージを以下で生成する。
    public function messages()
    {
        return [
            'title.required' => 'タイトルを入力してください。', //入力が無かった場合のエラー文
            'content.required' => '内容を入力してください。',
        ];
    }

    //validationでエラーがでた時にjsonで返す。
    protected function failedValidation(Validator $validator)
    {
        $response = response()->json([
            'status' => 400, //jsonの返事の中身のエラー番号
            'errors' => $validator->errors(),
        ],400); //実際に送られるresponse codeが400番 これが無いと、jsonでエラーメッセージは返ってくるけど送れらてくるのは200番のstatusOKとくる。

        //例外を知らせる。
        //throw new 例外クラス名(例外message)
        throw new HttpResponseException($response);
    }
}

ほい!これでOK。

あとはコントローラーを作っていくだけです!

Controllerの作成

<?php

namespace App\Http\Controllers;

use App\Models\Memo;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

//---------------------------------------
//以下より追加
//---------------------------------------
use App\Http\Requests\Memo\StoreMemoRequest;

class MemoController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */

     //一応一覧表示機能も
    public function index()
    {
        return response()->json([
            'success' => true,
            'message' => 'List Success!',
            'details' => Memo::all()
        ]);
    }

    //先にバリデーションをするのでStoreMemoRequestから受け取った値を$request変数へ
    public function store(StoreMemoRequest $request)
    {
        //バリデーションで問題が無ければ保存
        Memo::create($request->all());
        return response()->json([
            'success' => true,
            'message' => 'Insert success!',
            'details' => $request->all()
        ]);
    }

}

ほい!こんな感じですかね。

あ、api.phpを忘れていた。
ということで以下のように書いていきます。

{app_name}/routes/api.php
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\MemoController; //作成したMemoControllerを追加
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

//デフォルトで書いてあったやつ
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

//追加部分
//Resourceにする事でrestfulなroutingにこれだけで対応できる。
Route::Resource('memo', MemoController::class);

これでOKだ!

後はPOSTメソッドなのでpostmanを使って確認してみましょう。

postmanが良く分からない方は以下を見てみてくださいね。

【Postman】インストールと使い方【API実行ツール】

ほい、ほんならPOSTメソッドで送って本当に保存されるのか確認してみてください。

DBにPOSTMANから送信した値が入っていたら完成です!

あ、ちなみにapiを利用する際にはurlが変わって、今回の場合なら以下のようになります。

以下のpathにPOSTメソッドを投げてくださいね。

/api/memo

まとめ

バリデーションもこのように書いていけば、Controllerがすっきり書くことができますね。

FatControllerを避けるためにも意識していきたいところはたくさん。

コメント

タイトルとURLをコピーしました