Validating Requests

Introduction

In all real world, production APIs, you don't let the server run into errors and warnings to break the execution stack. That is why we use Request Validation. After all, why should show SQL Errors to the API consumers, when you can just validate the data sent yourself?

WARNING

This section assumes that you are already familiar with what endpoints are available from this package. If you are unsure please read the Available Requests section

Typical Laravel Usage

  1. In a typical Laravel application there are 2 ways to validate data sent, both of them are not usable in Api Auto Pilot. The first one would be to validate the request's incoming values in the controller using the validate() method which takes an array containing the formula of what the data sent should be.

  2. The other way that we could validate an incoming request to the server, would be to create our own request class, using php artisan make:request {myRequestClass} and then type hint it, into the controller method, that handles this particular request. Since we do not have access to the controller, what approach do we choose?

Solution

The answer is, mostly the second approach. To validate incoming requests using when already having Request Classes ready you simply add a $validationRequest array and set it to the Request class that you want to validate against.

public $validationRequest = [
    'create' => CreatePostModelRequest::class,
    'update' => UpdatePostModelRequest::class,
]

TIP

You can have many types of request validation for each CRUD operation. If you have different validation requirement for Creating and Updating, you can set the $requestValidations['create'] for creating, and $validationRequest['update'] for updating, to the value of the request class namespace. Api Auto Pilot will detect which CRUD operation you are doing at the moment and load up the appropriate validation class.

Let's see an example here. Lets a request class and validate the incoming values to create a Post model. Let's assume that to create a new Post model, the API consumer is required to provide a body JSON index, but to update it, it's not required.

First, we will 2 the request classes one by one.

php artisan make:request CreatePostModelRequest

WARNING

To not break your application's security measures, Api Auto Pilot, evaluates the return type of the authorize() method in your request class. If it returns a falsy value, the endpoint will result with an unauthorized response followed by a 401 UNAUTHORIZED HTTP Response Status Code

{
    "error": "unauthorized"
}

This command will result in creating a new CreatePostRequest.php file that is contained in the app/Http/Requests folder. In the rules() method set the required values that you want your request indexes to have. In our example, we will set that body index is required.


<?php
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreatePostModelRequest extends FormRequest
{
   
    public function authorize()
    {
        return true;
    }

   
    public function rules()
    {
        return [
            'body' =>'required'
        ];
    }
}

Next, we set this class to the $validationRequest variable in our model, which is App\Models\Post

<?php

namespace App\Models;

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

class Post extends Model
{
    use HasFactory;

    public $validationRequest = [
        'create' => CreatePostModelRequest::class,
    ]

    protected $fillable = [
        'body', 'title',
    ];

}

Now, lets see what happens if you try to make a POST Request to the endpoint /api/aap/post to create a new Post without providing a body parameter.

// Post Request to `/api/aap/post`
{
    "title": "creating a post without required body"
}

We get the following error response followed by a 422 - Unprocessable Content HTTP Response Code

{
    "message": "The body field is required.",
    "errors": {
        "body": [
            "The body field is required."
        ]
    }
}
Last Updated:
Contributors: GeorgeFourkas