Expand description
Typed handlers (18.28.0, #86): extractors as function arguments, any
IntoResponse as the return value, the route’s method and pattern
taken from the #[get]/#[post]/… attribute.
use rust_web_server::app::App;
use rust_web_server::error::AppError;
use rust_web_server::get;
use rust_web_server::handler::{Json, Path, State};
struct Db;
#[get("/posts/{id}")]
fn show_post(Path(id): Path<u64>, State(db): State<Db>) -> Result<Json<String>, AppError> {
let _ = db;
Ok(Json(format!("post {id}")))
}
let app = App::with_state(Db).route(show_post);The attribute turns show_post into a unit struct implementing
Handler (and AsyncHandler); the function as written stays callable
as show_post::call(…). Registration —
AppWithState::route,
Router::route,
AsyncAppWithState::route — reads the method and pattern from
RouteSpec, so the pattern the macro checked is the one that’s served.
The macro checks at compile time that the pattern’s parameters and the
Path argument agree: a route with parameters needs a Path (or
&PathParams) argument, a Path needs parameters, a tuple has one
element per parameter, names bound as Path(id) / Path((id, slug))
are parameters of the route, and a #[derive(FromPath)] struct’s
fields are exactly its parameters.
Each argument is extracted in order; the first that fails answers the request with its rejection (problem details, like rws’s own errors):
| Argument | Rejection |
|---|---|
Path<T> | 400 when a parameter doesn’t parse |
Query<T> (serde) | 400 when the query string doesn’t fit T |
Form<T> (serde) | 415 without an urlencoded Content-Type, 400 for a body that isn’t UTF-8, 422 when the fields don’t fit T |
Json<T> (serde) | 400 (as json::Json’s FromRequest) |
BodyText | 400 for a body that isn’t UTF-8 |
State<S>, &S, Body, RequestHeaders, RequestId, &Request, &ConnectionInfo, &PathParams | never |
any other FromRequest type (Validated<T>, your own) | its own |
Classic handlers — fn(&Request, &PathParams, &ConnectionInfo[, &S]) —
keep the old behaviour: the attribute only adds a doc comment and they
are registered with .get(pattern, handler) as before.
Structs§
- Body
- Raw request body bytes.
- Body
Text - Request body decoded as UTF-8 text.
- Form
- An
application/x-www-form-urlencodedbody deserialized intoT:Form(signup): Form<Signup>. Same field types asQuery. - Json
- A JSON extractor and responder backed by
serde_json. - Path
- The route’s parameters, parsed:
Path(id): Path<u64>for one,Path((id, slug)): Path<(u64, String)>for several, or a#[derive(FromPath)]struct whose fields are named after them. - Query
- The query string deserialized into
T:Query(page): Query<Page>. - Request
Headers - Clone of all request headers.
- Request
Id - The request’s correlation ID (the
X-Request-Idheader,RequestIdLayer’s default —request_id::DEFAULT_HEADER), for handlers that want it without reaching forRequestHeadersdirectly. - Request
Parts - What an extractor sees: the request, the route’s parameters, the connection and the app’s state.
- State
- The app’s shared state (
App::with_state(state)): a clone of itsArc.
Traits§
- Async
Handler - A typed handler for
AsyncAppWithState(http2): the route macros make one from anasync fn, and from every sync typed handler too. - From
Path - A type
Pathcan build from route parameters. - From
Request Parts - A typed handler argument: built from the
RequestParts, or a ready-to-send rejection. - Handler
- A typed handler for apps with state
S, made by the route macros from a function whose arguments are extractors. Register it with.route(h). - Into
Response - Implemented by any type that can be turned into an HTTP
Response. - Route
Spec - A route’s method and pattern, generated by
#[get("/path")]& co.
Type Aliases§
- Handler
Future - The future an
AsyncHandlerreturns.