> For the complete documentation index, see [llms.txt](https://core-foundation-doc.rupeshstha.com.np/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://core-foundation-doc.rupeshstha.com.np/http-and-application-layer/requests.md).

# Form Requests

Core Foundation's `BaseRequest` simplifies API validation by enforcing consistency and providing a structured lifecycle for shared rules.

## Rule Hierarchy (The "Shared Rules" Pattern)

Most API resources share 90% of their validation rules between creation and update. `BaseRequest` provides three hooks to eliminate duplication:

1. `baseRules()`: Rules shared by **all** methods.
2. `storeRules()`: Rules added/overridden for **POST** only.
3. `updateRules()`: Rules added/overridden for **PUT/PATCH** only.

### Merging Strategy

The foundation automatically merges these:

* **Store**: `baseRules()` + `storeRules()`
* **Update**: `baseRules()` + `updateRules()`

**Later keys win.** This allows you to define a field as `required` in `baseRules` and relax it to `sometimes` in `updateRules` without rewriting the entire ruleset.

```php
class UserRequest extends BaseRequest
{
    protected function baseRules(): array {
        return ['email' => ['required', 'email']];
    }

    protected function updateRules(): array {
        // Relax the required rule for partial updates
        return ['email' => ['sometimes', 'email']];
    }
}
```

## Route Parameter Merging

You often need to include route parameters (like a `{user_id}`) in your validation rules or use them as part of your unique ignore logic.

```php
protected function prepareForValidation(): void
{
    $this->mergeRouteParameters(['user']);
}
```

Now, `$this->validated()['user']` will contain the ID of the bound user.

## Unique Ignores with `routeModel()`

In update requests, you usually want to ignore the record's own ID during uniqueness checks. Use the `routeModel()` helper:

```php
protected function updateRules(): array
{
    return [
        'email' => [
            'sometimes', 'email',
            Rule::unique('users')->ignore($this->routeModel('user')),
        ],
    ];
}
```

## Self-Documenting Metadata

`BaseRequest` supports the `#[ApiRequest]` attribute and `schema()` method, which are used by the [API Doc Generator](/apm-and-devtools/api-docs.md).

```php
#[ApiRequest(description: 'Update user profile.', tags: ['Profile'])]
class ProfileRequest extends BaseRequest
{
    public function schema(): array
    {
        return [
            BodyParam::make('bio')
                ->type('string')
                ->description('Short user bio.')
                ->example('Software architect.')
                ->optional(),
        ];
    }
}
```

## Authorization

`authorize()` returns `true` by default. If it returns `false`, the foundation automatically returns a standardized JSON 403 response. Authorization should ideally be handled at the **Policy** layer, not inside the request.

## Container Binding

Form requests are **not registered in the service container**. Laravel auto-resolves them per request via method injection — no binding needed.
