Customizing validation error messages in Laravel

Constantin Druc ยท 29 Mar, 2022

Sometimes, because of the way we name our inputs or request parameters, we end up showing improper validation error messages that just don't look right for the end-user.

Here's an example:

1<?php
2 
3namespace App\Http\Controllers\Api;
4 
5use App\Http\Controllers\Controller;
6 
7class CartItemsController extends Controller
8{
9 public function store()
10 {
11 request()->validate([
12 'qty' => ['required', 'integer', 'min:10'],
13 'productId' => ['required', 'exists:products,id']
14 ]);
15 }
16}

We validate a qty field, but we're using the abbreviation, not the full quantity word. And while this is acceptable in code; everybody knows what it means, when it comes to displaying the error messages to the end-user, we should avoid such abbreviations and use the full version instead.

This gets even worse when we're dealing with parameter names like productId.

While the first error is decent, the second one is a bit weird to say the least. As an end user, I would expect something in the lines of "The product is no longer available."

To fix this, we can customize the error messages by passing a second array as an argument, containing keys formed using the name of the parameter, dot, and then the name of the validation rule - the value will be the error message we want to display.

In the case of the `min` validation rule, to get the minimum required value we can use the rule name as a placeholder `:min`.

1<?php
2 
3namespace App\Http\Controllers\Api;
4 
5use App\Http\Controllers\Controller;
6 
7class CartItemsController extends Controller
8{
9 public function store()
10 {
11 request()->validate([
12 'qty' => ['required', 'integer', 'min:10'],
13 'productId' => ['required', 'exists:products,id']
14 ], [
15 'qty.min' => 'The quantity must be at least :min.',
16 'productId.exists' => 'The product is no longer available.'
17 ]);
18 }
19}

And, of course, we can do the same thing using form request objects. Only that now, the error messages array will be returned by a newly added messages() method:

1<?php
2 
3namespace App\Http\Requests;
4 
5use Illuminate\Foundation\Http\FormRequest;
6 
7class StoreCartItemRequest extends FormRequest
8{
9 /**
10 * Determine if the user is authorized to make this request.
11 *
12 * @return bool
13 */
14 public function authorize()
15 {
16 return true;
17 }
18 
19 /**
20 * Get the validation rules that apply to the request.
21 *
22 * @return array
23 */
24 public function rules()
25 {
26 return [
27 'qty' => ['required', 'integer', 'min:10'],
28 'productId' => ['required', 'exists:products,id']
29 ];
30 }
31 
32 public function messages()
33 {
34 return [
35 'qty.min' => 'The quantity must be at least :min.',
36 'productId.exists' => 'The product is no longer available.'
37 ];
38 }
39}

This was tiny tip #3. I hope you found it useful!