HOW TO IMPROVE LARAVEL REQUESTS
Published: 2023-08-16 14:18:44

Laravel is a free and open-source PHP web framework, created by Taylor Otwell and intended for the development of web applications following the model–view–controller (MVC) architectural pattern and based on Symfony ([wiki](https://en.wikipedia.org/wiki/Laravel)).

The Framework provides a lot of features to help developers improve APIs. To ensure that your API is developed in a secure way, Laravel offers classes that help in the security of the data being transited within the server. In this article you will learn how to create and validate data with this tool.

## &nbsp;
## Requests

When a payload data is sent to the backend server it goes throug several processes, the most common validation proccess is created using a Laravel Request Object, as default, for every route that uses a method in controller Laravel sends as parameter a Request Object as a dependecy injection ([learn more] (https://en.wikipedia.org/wiki/Dependency_injection)). For example:

```php
namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index(Request $request)
    {
        //
    }
}
```
> The Request Object located at `Illuminate\Http\Request` is sent as a parameter to route method

## &nbsp;
## Request Object

The Request Object provided by Illuminate has some methods that improves your code security and makes it cleaner. For Example:

```php
public function index(Request $request)
{
    $name = $request->input('name'); // secure way

    $name = $request->name; // insecure way
}
```

When you get a value from request without using `input()`, `get()` or `post()` methods make instabilities in code, cause you're trying to access a property that non exists in a class by default.
Those methods receives a second paramenter as default value if request parameter don't exists or it's null.

```php
public function index(Request $request)
{
    // returns John Doe if name parameter don't exists in request
    return $request->input('name', 'John Doe'); 
}
```

## &nbsp;
## Validating Requests

To make sure that the parameter is being sent correctly by the request, the Request object offers a method called `validate()` in which it receives an array, the keys of this array must be the name of the input to be validated and the value of the array being the rule for validation. For example:

```php
public function index(Request $request)
{
    $request->validate([
        'name' => 'string' 
    ]);
}
```
> In this case, the array informs that the "name" parameter sent through the Request must be a string, if this validation fails, the server returns a response with error code 422 (Unprocessable Entity), if the route is accessed through some browser, the request will be redirected to its origin, being possible to capture the error through a blade template.

### &nbsp;

```html
<!-- resources/views/form.blade.php -->

@error('name')
   <div class="alert alert-danger">
       {{ $message }}
   </div>
@endif
```
> You can edit the request validation return message in `validation.php` located at `resources/lang/en`

## &nbsp;
## Creating Custom Requests

In Laravel, it is possible to create your own Request objects, with customized validation methods and rules, in addition to creating your own attributes, thus increasing code stability. Custom requests also make your Controller code cleaner. To create a new Request object in your project, run the artisan command:

```bash
php artisan make:request StoreUserRequest
```

### &nbsp;

Conventionally it is recommended to use the "Request" suffix for every request file you create. In order for you to maintain a clean and standardized code, it is recommended that you create a Request object for each and every request of a CRUD from your system, in a CRUD of users for example:
- StoreUserRequest
- GetUserRequest
- UpdateUserRequest
- DeleteUserRequest

When you open the request file generated through the artisan command, you will see a file of the class you created with two standard methods, namely the `authorize()` method that returns a boolean and the `rules()` method that returns a array.

### &nbsp;
### Authorize Method

```php
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize(): bool
{
    return false;
}
```

The authorize method is responsible for returning a boolean, when this boolean is false, Laravel will automatically return an error to the client side with code 401 (Unauthorized), this means that your authorize method will be the method that determines whether the request being made is allowed to proceed or whether it should be denied. Normally, the authorize method returns a validation to proceed with the request only if the user is logged into the system.

```php
public function authorize(): bool
{
    return auth()->check();
}
```

> In this case, the request will be accepted only if the user is authenticated in the system.

### &nbsp;
### Rules Method

```php
public function rules(): array
{
    return [
        //
    ];
}
```

The rules method created after generating a Request file is responsible for returning an array of rules for the request to proceed successfully, the logic of the array implies that the keys must receive the names of the fields you want to validate and the values ​​must receive the type of validation that must be done.

```php
public function rules(): array
{
    return [
        'email' => 'email|max:255',
        'name'  => 'string|max:255'
    ];
}
```

In this case, the rule says that, as a requirement, the email field to be received in the request must be of type “email” and have a maximum of 255 characters. The "name" field must respect the "string" format and contain only 255 characters. These values ​​can also be organized by an array. For example:

```php
public function rules(): array
{
    return [
        'email' => ['email', 'max:255'],
        'name'  => ['string', 'max:255']
    ];
}
```
> There are several validations that can be done even with databases. ([Learn more](https://laravel.com/docs/validation))

### &nbsp;
### Creating Custom Rule

With Laravel it is also possible to create a custom rule for your request, for you to generate a rule class you must run the command:

```bash
php artisan make:rule UppercaseRule
```

When running the above command, Laravel will create a class called UppercaseRule in the `app/rules` folder, in this class you can find a method called `validate`

```php
public function validate(string $attribute, mixed $value, Closure $fail): void
{
     //
}
```

The method receives 3 parameters: 
- `$attribute`: The name of field that will be validated
- `$value`: The value of field that will be validated
- `$fail`: A function that will execute indicating that field is not valid

```php
public function validate(string $attribute, mixed $value, Closure $fail): void
{
    if (strtoupper($value) !== $value) {
        $fail('The :attribute must be uppercase.');
    }
}
```

In this case, the method will validate if a value is different from itself in upper case and then execute the fail closure passing a message as default. You can notice that the method has the `void` return type, that is, the method must not return any value, so if the `$fail` function is not executed, Laravel will interpret the response as positive, thus following the request process.

> The example thus shows the functionality in version 10.x of Laravel, if you want to perform these steps in a different version, I suggest you check correctly how it should be done in the official documentation. ([here](https://laravel.com/docs/validation))

Finally, to choose which field a certain rule should be applied to, you must go back to the method
`rules()` found in your Request class and instantiate or reference the rule class

```php
public function rules(): array
{
    return [
        'email' => ['email', 'max:255', UppercaseRule::class] // or (new UppercaseRule),
        'name'  => ['string', 'max:255']
    ];
}
```

### &nbsp;
### Conclusion
After learning a little more about How To Use Improve Requests In Laravel, we can see how useful are the tools that Laravel provides for validate any API data. Always remember to stay on top of the official Laravel documentation, which is always kept up to date ([Laravel Documentation](https://laravel.com/docs))