Web frameworks
Validation filters for Warp 0.3 and 0.4. Shared rules (status codes, error body, coercion, headers and cookies) are on the web adapters overview.
Install
Cargo.toml
[dependencies]
vld = "0.5"
vld-warp = "0.5"
warp = { version = "0.4", features = ["server"] }
The dependency is warp >=0.3, <0.5; there are no version features, Cargo picks the warp you use. MSRV 1.85, see MSRV.
Example
use vld_warp::prelude::*;
use warp::Filter;
vld::schema! {
#[derive(Debug, Clone)]
pub struct CreateUser {
pub name: String => vld::string().min(2),
pub email: String => vld::string().email(),
}
}
vld::schema! {
#[derive(Debug, Clone)]
pub struct UserId {
pub id: i64 => vld::number().int().min(1),
}
}
#[tokio::main]
async fn main() {
let create = warp::post()
.and(warp::path("users"))
.and(warp::path::end())
.and(vld_json::<CreateUser>())
.map(|u: CreateUser| warp::reply::json(&serde_json::json!({ "name": u.name })));
let get = warp::get()
.and(warp::path("users"))
.and(vld_param::<UserId>("id"))
.and(warp::path::end())
.map(|p: UserId| format!("user #{}", p.id));
warp::serve(create.or(get).recover(handle_rejection))
.run(([127, 0, 0, 1], 3030))
.await;
}
API
| Item | Purpose |
|---|---|
vld_json::<T>() | JSON body; 415 without a JSON Content-Type |
vld_json_limit::<T>(bytes) | Same with an explicit body limit |
vld_form::<T>() / vld_form_limit::<T>(bytes) | application/x-www-form-urlencoded body |
vld_query::<T>() | Query string (an absent query is {}) |
vld_param::<T>(name) | One path segment, wrapped as {name: value} |
vld_path::<T>(&names) | All remaining segments, mapped to names in order |
validate_path_params::<T>(&pairs) | Validate (name, raw) pairs you extracted yourself |
vld_headers::<T>() | Request headers |
vld_cookie::<T>() | Cookies from every Cookie header |
VldRejection | Custom rejection: status(), body(), error() |
handle_rejection | Recovery function for .recover() |
prelude | All of the above plus vld::prelude::* |
Path values are percent-decoded before coercion.
Rejection handling
Without .recover(handle_rejection) a VldRejection reaches warp's default handler, which does not know it. handle_rejection answers:
| Rejection | Status |
|---|---|
VldRejection | its own status (422 / 413 / 415) and JSON body |
PayloadTooLarge | 413 |
UnsupportedMediaType | 415 |
LengthRequired | 411 |
MissingHeader, InvalidHeader, MissingCookie, InvalidQuery | 400 |
MethodNotAllowed | 405 |
| not found | 404 |
| anything else | 500 |
Non-vld rejections get {"error": "<message>"}.
Gotchas
- Bodies are read as a stream and stop at the limit (2 MiB by default), with or without
Content-Length, so chunked uploads are limited too. vld_pathneeds exactly as many remaining segments as names; any other count is a 404. Usevld_paramorvalidate_path_paramswhen static and dynamic segments are interleaved.- Since 0.5 unknown rejections are 500, not 404.