Appearance
Handling Requests in Laravel
1. Introduction
In Laravel, HTTP requests are typically handled with the Illuminate\Http\Request class:
php
use Illuminate\Http\Request;This base class provides the features you need for most cases. When validation or authorization becomes more complex, prefer dedicated Form Request classes that extend Illuminate\Foundation\Http\FormRequest.
2. Avoid ->input(), ->get(), and ->all()
$request->input('field')/$request->get('field'): Returnmixed, which weakens type safety.$request->all(): Returns an array of all raw input without casting or filtering, which increases mass assignment risk, can expose sensitive fields, and makes data-tampering attacks easier.
Prefer these typed alternatives:
| Method | Return type |
|---|---|
$request->string('name')->value() | string (trimmed and cast) |
$request->integer('age', $defaultValue) | int |
$request->float('price', $defaultValue) | float |
$request->boolean('flag', $defaultValue) | bool |
$request->array('items') | array |
$request->enum(MyEnum::class, 'status') | MyEnum (or null if nullable) |
$request->file('avatar') | UploadedFile |
These methods keep types safe and make the code clearer.
3. Validation rules
- Always write rules as an array, not a pipe-separated string (
|).
php
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'email', Rule::unique('users', 'email')],
'status' => ['required', Rule::enum(UserStatus::class)],
'website' => ['nullable', 'url', new IsValidDomain()],
];
}4. Extract complex logic into a Custom Rule
When validation logic becomes complex, move it out of the Form Request rules() method into a Custom Validation Rule. This separates concerns, improves reuse, keeps Form Requests readable, and makes the rule easy to unit test on its own.
Creating and using a Custom Rule
Create the class with Artisan:
bash
php artisan make:rule IsValidPromotionCodeThe Rule class implements Illuminate\Contracts\Validation\Rule and defines passes($attribute, $value) and message():
php
final class IsValidPromotionCode implements Rule
{
public function passes($attribute, $value): bool
{
return Promotion::query()
->where('code', $value)
->where('expires_at', '>', now())
->where('is_active', true)
->exists();
}
}Use the rule in a Form Request:
php
'promo_code' => ['nullable', 'string', 'max:50', new IsValidPromotionCode()],5. Form Request validation and typed access
When a FormRequest is type-hinted in a controller/action parameter, Laravel validates it before calling the method. Once the method runs, fields declared in rules() have passed validation, so typed accessors such as array(), integer(), and string() are safe and do not bypass validation.
Prefer typed accessors when application logic needs typed values. Do not read from validated() and parse those values again: it returns mixed values, which weakens type safety and PHPStan analysis. Use validated() when passing the accepted payload directly to another API, such as model creation.
php
public function store(MyFormRequest $request): JsonResponse
{
$user = User::query()->create($request->validated());
return $this->ok($user);
}6. API response
- Always use the
App\Concerns\HasApiResponsetrait in Actions for consistent JSON responses. - Use
self::ok($data, $message)for successful responses. - Use
self::exception($e)inside acatchblock to return detailed errors when an exception occurs.
Example in IndexProductAction:
php
try {
return self::ok($result);
} catch (Throwable $e) {
return self::exception($e);
}7. Best practices summary
- Import:
use Illuminate\Http\Request; - Do not use:
->input(),->get(),->all() - Use:
->string(),->integer(),->array(),->enum()… - Validation: array-form rules, Custom Rule
- Logic: extract into Service/Action; do not put it in the Request
- Type safety: PHPStan-friendly, easier to test and maintain

