Form requests authorise, then validate, then hand you a struct.
A form request is the rules for an input plus who may send it. The controller receives a typed value that has passed both — and the same rules describe the endpoint in the generated OpenAPI document.
What you get
authorizeruns first: an unauthorised caller gets a 403 without the input being read.- Failures answer 422 in one documented shape, with per-rule messages you can override.
- Only the fields the rules name reach the struct.
- The OpenAPI document is generated from the validator’s rules, so the schema cannot drift from what is enforced.
In the docs
src/app/http/requests/store_post.rs
use rainier_framework::auth::AuthenticatedUser;
use rainier_framework::prelude::*;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct StorePostRequest {
pub title: String,
pub body: String,
}
#[async_trait]
impl FormRequest for StorePostRequest {
fn rules() -> RuleSet {
vec![
field("title", [Rule::Required, Rule::String, Rule::Between(3.0, 120.0)]),
field("body", [Rule::Required, Rule::String, Rule::Min(10.0)]),
]
}
async fn authorize(request: &Request) -> bool {
request.extension::<AuthenticatedUser<User>>().is_some()
}
}
Up close
Select an image to see it full size.