いずみこんな悩みを解決できる記事を書きました!
僕は現役フリーランスエンジニア(歴10年)で、資格は13個保有しています。
「Laravelのコントローラーにバリデーションをベタ書きしていて読みにくい」と感じていませんか?
コントローラーのstoreメソッドやupdateメソッドに$request->validate() を並べていくと、処理が縦に長くなって見通しが悪くなります。
FormRequestを使えば、バリデーションのルールとエラーメッセージをコントローラーの外へ切り出せます。



フォームリクエストはフォーム画面でもAPIでも使う基本機能なので、丁寧に解説します。
ということで、本記事ではLaravelのFormRequestでバリデーションを実装する方法を解説します。



すぐ読み終わるので、ぜひ最後まで読んでくださいませ。
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
【Laravel】FormRequestでバリデーションを実装する方法
早速ですが、LaravelのFormRequestでバリデーションを実装する手順を見ていきます。
FormRequestとは何か
FormRequestは、1つのリクエストに対するバリデーションと認可のロジックをまとめる専用クラスです。
コントローラーのメソッド引数にFormRequestクラスを型指定すると、コントローラーの処理が動く前にバリデーションが自動で実行されます。
検証に失敗した場合は、フォーム画面なら自動でリダイレクトとエラー表示、JSONを期待するリクエストなら422のレスポンスが返ります。



コントローラーは「検証済みの値を受け取って処理するだけ」の状態になります。
FormRequestクラスを作成する
まずはartisanコマンドでFormRequestクラスを作成します。
ターミナルでmake:requestコマンドを実行します。
php artisan make:request StorePostRequestapp/Http/Requests/StorePostRequest.php が生成されます。
authorizeメソッドがtrueを返すと、リクエストの実行が許可されます。
ログインユーザー全員に許可したい場合はtrueを返すだけで問題ありません。
falseを返すと403エラーになり、コントローラーの処理は実行されません。
rulesメソッドが返す配列に、フィールドごとのバリデーションルールを定義します。



次のコードで具体的な中身を見ていきます。
rulesメソッドにバリデーションルールを定義する
生成されたクラスを編集し、authorize・rules・messages・attributesの4つのメソッドを整えます。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StorePostRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'],
'status' => ['required', 'in:draft,published'],
'published_at' => ['nullable', 'date'],
];
}
public function messages(): array
{
return [
'title.required' => 'タイトルは必須です。',
'title.max' => 'タイトルは255文字以内で入力してください。',
'status.in' => 'ステータスの値が不正です。',
];
}
public function attributes(): array
{
return [
'title' => 'タイトル',
'body' => '本文',
];
}
}rulesメソッドでは、ルールをパイプ区切りの文字列('required|string')ではなく配列で書く方が、条件が増えたときに読みやすくなります。
messagesメソッドで「ルールごとのエラーメッセージ」、attributesメソッドで「項目名の表示」を上書きできます。
コントローラーでフォームリクエストを受け取る
コントローラーのメソッド引数に、作成したStorePostRequestを型指定します。
<?php
namespace App\Http\Controllers;
use App\Http\Requests\StorePostRequest;
use App\Models\Post;
class PostController extends Controller
{
public function store(StorePostRequest $request)
{
$validated = $request->validated();
$post = Post::create($validated);
return redirect()->route('posts.show', $post);
}
}storeメソッドの中に入った時点で、すでにバリデーションは通過済みです。
$request->validated() は、rulesメソッドに定義したキーだけを含む配列を返します。
一部の項目だけ欲しいときは$request->safe()->only(['title', 'body']) のように絞り込めます。



フォームから送られた余計なパラメータがPost::create() に混ざらないので、Mass Assignment対策にもなります。
エラーメッセージと項目名を日本語にする
messagesメソッドは「フィールド名.ルール名」をキーにして、個別のメッセージを差し替えます。
全ルール共通の文言(「〜は必須です」など)を日本語化したい場合は、lang/ja/validation.php を用意する方法もあります。
attributesメソッドで項目名を日本語にしておくと、共通文言の:attribute 部分が「タイトル」「本文」に置き換わります。
prepareForValidationで入力値を整形する
バリデーション前に値を加工したいときは、prepareForValidationメソッドを使います。
<?php
use Illuminate\Support\Str;
// StorePostRequest クラス内に追記する
protected function prepareForValidation(): void
{
$this->merge([
'slug' => Str::slug((string) $this->input('title')),
'title' => trim((string) $this->input('title')),
]);
}mergeメソッドでリクエストに値を差し込むと、加工後の値がrulesメソッドの検証対象になります。
前後の空白除去やslugの自動生成など、コントローラーに書きがちな下処理をFormRequest側へ寄せられます。



整形とバリデーションが1つのクラスに集まるので、入力の仕様を追いやすくなります。
afterメソッドで項目をまたいだ検証をする
「statusがpublishedのときだけpublished_atが必須」のような、複数フィールドにまたがる検証はrulesの配列だけでは書きにくくなります。
Laravel 11以降で追加されたafterメソッドを使うと、追加の検証をクロージャで書けます。
<?php
use Illuminate\Validation\Validator;
// StorePostRequest クラス内に追記する
public function after(): array
{
return [
function (Validator $validator) {
if ($this->input('status') === 'published'
&& ! $this->input('published_at')) {
$validator->errors()->add(
'published_at',
'公開する場合は公開日時を入力してください。'
);
}
},
];
}afterメソッドはクロージャの配列を返し、rulesの検証が終わったあとに順番に実行されます。
古いバージョンではwithValidatorメソッドで同じことができるので、環境に合わせて選びます。
APIでバリデーションエラーをJSONで返す
リクエストのAcceptヘッダーがJSONを示している場合、FormRequestは自動で422のJSONレスポンスを返します。
レスポンスの形を自分で決めたいときは、failedValidationメソッドを上書きします。
<?php
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
// StorePostRequest クラス内に追記する
protected function failedValidation(Validator $validator): void
{
throw new HttpResponseException(response()->json([
'message' => '入力内容にエラーがあります。',
'errors' => $validator->errors(),
], 422));
}APIとフォーム画面で同じFormRequestを使い回す場合は、$this->expectsJson() で分岐させる書き方も選べます。



フロント側は「errorsキーにフィールド名ごとの配列が入る」と決めておくと扱いやすいです。
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
【厳選】フリーランスエンジニアにおすすめなエージェント3選


フリーランスエンジニアになるにはエージェントから案件をもらう必要があります。
僕が実際に利用しているおすすめエージェントを紹介しますね。



エージェントは必ず複数登録してください。
担当者によっては「全然案件紹介してくれない…」みたいなこともあるので…
僕は実際に5つのエージェントを使い回していますよ。
フリーランスを始めるなら「レバテックフリーランス


」
- 業界最大級の案件数。
- 業界トップクラスの高単価報酬、低マージン(平均年収862万円)。
- 案件参画中のフォローの充実。
※詳細は「【業界最大手】レバテックフリーランスとは?メリットや利用手順を解説!」を参照。
レバテックフリーランス
![]()
![]()
とにかく案件数が多いので、とりあえず登録しておけば間違いないエージェントです!



僕もはじめてフリーランスの案件を貰ったのはレバテックフリーランス
![]()
![]()
保有している案件数が多いので、業務経験がなくても何かしらの案件は紹介してもらえますよ(僕はJavaの経験3年でも案件を貰えました)。
手厚い保障を重視したいなら「Midworks


」
- 手厚い保障で正社員並みの安心感。
- 還元率60%超え&単価公開でクリアな契約。
- 給与保障制度(審査あり)。
Midworks
![]()
![]()
フリーランスを目指しているけど不安な方や保障を重視したい方におすすめです。



僕も何度か案件を紹介してもらいました。
自分のスキルに合った案件を紹介してもらえましたし、電話のやり取りも非常に丁寧でした。
週2〜3日の案件探しなら「ITプロパートナーズ


」
- IT案件に特化したフリーランスエージェント。
- 週2〜3日の案件が豊富。
- リモート案件が多く、直エンドなので単価も高い。
※詳細は「【週2・3案件】ITプロパートナーズとは?メリットや利用手順を解説!」を参照。
ITプロパートナーズ
![]()
![]()
週2〜3日から参画できる案件が豊富なので、起業したい人にもおすすめです。



週2〜3日の案件はある程度スキルがないと紹介してもらえない印象です。
とはいえ、週5の案件ももちろんありますし、僕が利用した時は迅速・丁寧に対応していただきました!
よくある質問
authorizeメソッドはtrueを返すだけでよいですか?
権限チェックが不要ならtrueで問題ありません。
投稿の所有者だけ更新を許可したい場合などは、authorizeメソッドの中でGateやPolicyを呼び、真偽値を返します。
検証済みのデータだけを受け取るにはどうしますか?
$request->validated() でrulesに定義したキーだけの配列を取得できます。
一部だけ欲しいときは$request->safe()->only([...]) やexcept([...]) を使います。
フォームリクエストをテストできますか?
機能テストでエンドポイントにリクエストを送り、assertInvalid() とassertValid() で結果を検証するのが手軽です。
rulesメソッド単体の確認なら、クラスをインスタンス化してrulesの戻り値を配列として比較する方法もあります。
まとめ
今回は、LaravelのFormRequestでバリデーションを実装する方法について解説しました。
以下が本記事のまとめになります。
- おすすめ本
Laravelの勉強なら「PHPフレームワーク Laravel入門 第2版



最後までお読みいただき、ありがとうございました!
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
- クソおすすめ本



海外のエンジニアがどういった思考で働いているかが理解できます。
海外に行く気はないけど海外エンジニアの動向が気になる雑魚エンジニアにおすすめです(本当におすすめな本しか紹介しないのでご安心を)。









