Request
In Evo, you can access request value by attaching request attributes such as Query
, Cookie
, Header
, Param
, Body
, etc to your method parameters. Then Evo will automatically inject corresponding value to attached parameter. Evo will also automatically validate and cast the value according to parameter type and definition.
Before using those attributes, make sure you have import their full class names.
use Emsifa\Evo\Http\Param;use Emsifa\Evo\Http\Query;use Emsifa\Evo\Http\Header;use Emsifa\Evo\Http\Cookie;use Emsifa\Evo\Http\Body;
Query
Attribute#
Query
attribute is used to get a query value from HTTP request.
#[Get]public function index(#[Query] int $page){ // ...}
In example above, Evo will:
- Getting
request()->query('page')
value. - Apply validation to the value to make sure it's numeric.
- Cast value to
int
. - Inject casted value to
$page
parameter.
If you want to use different query and parameter name, you can set $key
parameter to Query
attribute like an example below:
#[Get]public function index(#[Query('p')] int $page){ // ...}
In example above Evo will get p
query value and inject it to $page
parameter.
If you want to make it optional, you can just give default value to the parameter. For example:
#[Get]public function index(#[Query('q')] int $page = 1){ // ...}
Or you can also make it nullable, for example:
#[Get]public function index(#[Query('q')] ?int $page){ // ...}
Param
Attribute#
Param
attribute is used to get URI parameter value.
#[Get('users/{id}')]public function index(#[Param] int $id){ // ...}
Like Query
attribute before, Evo will do validation, type casting, and inject the value to the $id
parameter.
Header
Attribute#
Header
attribute is used to get a header value from HTTP request.
#[Get('users/{id}')]public function index(#[Header('user-agent')] string $userAgent){ // ...}
In example above, Evo will get user-agent
header value and inject it to the $userAgent
parameter.
Cookie
Attribute#
Cookie
attribute is used to get a cookie value from HTTP request.
#[Get('users/{id}')]public function index(#[Cookie] string $token){ // ...}
In example above, Evo will get token
cookie value and inject it to the $token
parameter.
Body
Attribute#
Body
attribute is used to get value from HTTP request body.
To use Body
attribute you have to use DTO
class as the type of your parameter.
You can create DTO
class by using evo:make-dto
command.
In this example, we will inject request body value as RegisterDto
instance into register
method.
First, we have to generate RegisterDto
class with command:
php artisan evo:make-dto RegisterDto name:string email:string password:string password_confirmation:string
Then you will get app/Dtos/RegisterDto.php
file with code like this:
<?php
namespace App\Dto;
use Emsifa\Evo\Dto;
class RegisterDto extends Dto{ public string $name; public string $email; public string $password; public string $password_confirmation;}
Now you may want to add some extra validations to each properties. You can do that by attaching rules attribute like an example below:
<?php
namespace App\Dto;
use Emsifa\Evo\Dto;use Emsifa\Evo\Rules;
class RegisterDto extends Dto{ #[Rules\Required] public string $name;
#[Rules\Required] #[Rules\Email(message: "Incorrect email format")] #[Rules\Unique(table: 'users', column: 'email', message: "Email already used by someone")] public string $email;
#[Rules\Required] #[Rules\Min(6, message: "Password must have at least 6 characters")] public string $password;
#[Rules\Required] #[Rules\SameWith('password', message: "Password confirmation doesn't match with password")] public string $password_confirmation;}
Behind the scene, code above will do validation like Laravel code below:
$request->validate([ 'name' => 'required', 'email' => 'required|email|unique:users,email', 'password' => 'required|min:6', 'password_confirmation' => 'required|same:password',], [ 'email.email' => "Incorrect email format", 'email.unique' => "Email already used by someone", 'password.min' => "Password must have at least 6 characters", 'password_confirmation.same' => "Password confirmation doesn't match with password",]);
After defining validation rules to properties, you can inject RegisterDto
instance to your method like any other attributes before, but with Body
attribute.
#[Post('register')]public function register(#[Body] RegisterDto $dto){ // ...}
And there you go. Same like any other attributes. Evo will validate the values, resolving RegisterDto
instance, and inject it to $dto
parameter.
#
Uploaded FileYou can get uploaded files in two ways below:
- Using DTO class and
Body
attribute. - Using
File
attribute.
Body
attribute#
1. Getting uploaded file using DTO and To get uploaded file using DTO, you can just add a property with type Illuminate\Http\UploadedFile
.
<?php
namespace App\Dto;
use Emsifa\Evo\Dto;use Emsifa\Evo\Rules;use Illuminate\Http\UploadedFile;
class UpdateProfileDto extends Dto{ #[Rules\Required] public string $name;
#[Rules\Mimes(['jpeg', 'png'])] #[Rules\Image] public ?UploadedFile $avatar = null;}
In example above Evo will inject $avatar
property with request()->file('avatar')
value.
File
attribute#
2. Getting uploaded file using If you want directly inject uploaded file instance to your controller method, you can use File
attribute like an example below:
#[Post('register')]public function register( #[Body] RegisterDto $dto, #[File(rules: 'required|mimes:jpeg,png|image')] UploadedFile $avatar,){ // ...}
LoggedUser
Attribute#
LoggedUser
attribute is used to get current logged user instance from request()->user()
.
You can use it like any other request attributes before, just make sure if its optional, you have to make it nullable and set default value to null.
public function show( #[Param] int $id, #[LoggedUser] ?User $user = null,){ // ...}
#
Create Custom Request AttributeYou can create your own request getter attribute by creating a class implementing Emsifa\Evo\Contracts\RequestGetter
interface.
For example we will create JwtToken
attribute to retrieve JWT token from header or cookie.
First, create a file app/Http/Attributes/JwtToken.php
.
Then you can use code below:
<?php
namespace App\Http\Attributes;
use Attribute;use Emsifa\Evo\Contracts\RequestGetter;use Illuminate\Http\Request;use Illuminate\Support\Str;use ReflectionParameter;use ReflectionProperty;
#[Attribute(Attribute::TARGET_PARAMETER)]class JwtToken implements RequestGetter{ public function getRequestValue(Request $request, ReflectionParameter | ReflectionProperty $reflection): mixed { $token_from_header = $request->header("authorization"); $token_from_cookie = $request->cookie("token");
return $token_from_header ? Str::after($token_from_header, "Bearer ") : $token_from_cookie; }}
Now you can use it like any other request attributes like following code:
public function doSomething(#[JwtToken] ?string $token = null){ // ...}
In most case you may want to validate the value to make sure it is safe for Evo to type cast it and inject it to your parameter.
To do that, you can implement Emsifa\Evo\Contracts\RequestValidator
like an example below:
<?php
namespace App\Http\Attributes;
use Attribute;use Emsifa\Evo\Contracts\RequestGetter;use Emsifa\Evo\Contracts\RequestValidator;use Illuminate\Http\Request;use Illuminate\Support\Str;use Illuminate\Support\Facades\Validator;use ReflectionParameter;use ReflectionProperty;
#[Attribute(Attribute::TARGET_PARAMETER)]class JwtToken implements RequestGetter, RequestValidator{ public function getRequestValue(Request $request, ReflectionParameter | ReflectionProperty $reflection): mixed { $token_from_header = $request->header("authorization"); $token_from_cookie = $request->cookie("token");
return $token_from_header ? Str::after($token_from_header, "Bearer ") : $token_from_cookie; }
public function validateRequest(Request $request, ReflectionProperty | ReflectionParameter $reflection) { $data = [ "token" => $this->getRequestValue($request, $reflection) ];
$rules = [ "token" => "required|string", ];
Validator::make($data, $rules)->validate(); }}
Now Evo will run validateRequest
before type casting it's value and inject it to your parameter.