URL encoded
URL encoding, also known as percent encoding, is one
of the formats used by browsers to encode the data submitted via a POST web form.
You can use UrlEncodedBody<T> to work with URL encoded payloads:
it parses the raw request body into an instance of the type T you specified.
use pavex::http::StatusCode;
use pavex::post;
use pavex::request::body::UrlEncodedBody;
#[derive(serde::Deserialize)]
pub struct HomeListing {
address: String,
price: u64,
}
#[post(path = "/search")]
pub fn search_form(body: &UrlEncodedBody<HomeListing> /* (1)! */) -> StatusCode {
println!(
"New home listing at {}, for ${}",
body.0.address, body.0.price
);
// [...]
}
- The parsed body is injected as an input parameter.
The whole request body is buffered in memory before being deserialized.
Imports
To use UrlEncodedBody<T> in your application, you need to import its constructor from pavex:
use pavex::{Blueprint, blueprint::from};
pub fn blueprint() -> Blueprint {
let mut bp = Blueprint::new();
bp.import(from![pavex]);
// [...]
}
Deserialization
The newly defined struct must be deserializable—i.e. it must implement
the serde::Deserialize trait.
You can derive serde::Deserialize in most cases.
Unsupported field types
UrlEncodedBody<T> doesn't support deserializing nested structures.
For example, the following can't be deserialized from the wire using UrlEncodedBody<T>:
use serde::Deserialize;
#[derive(Deserialize)]
pub struct UpdateUserBody {
address: Address
}
#[derive(Deserialize)]
pub struct Address {
street: String,
city: String,
}
If you need to deserialize nested structures from a URL encoded body,
you might want to look into writing your own extractor on top of a crate like
serde_qs.
Avoiding allocations
If you want to minimize memory usage, you can try to avoid unnecessary heap memory allocations when deserializing string-like fields from the body of the incoming request. Pavex supports this use case—you can borrow from the request body.
Percent-encoding
It is not always possible to avoid allocations when handling a URL encoded body.
Fields and values in a URL encoded body must comply with the restriction of the URI specification:
you can only use a limited set of characters.
If you want to use a character that's not URL-safe, you
must percent-encode it.
For example, if you want to use a space in a field name or a field value, you must encode it as %20.
A string like John Doe becomes John%20Doe when percent-encoded.
UrlEncodedBody<T> automatically decodes percent-encoded strings for you. But that comes at a cost:
Pavex must allocate a new String if the value is percent-encoded.
Cow
We recommend using Cow<'_, str> as your field type for string-like parameters.
It borrows from the buffered request body if possible, it allocates a new String if it can't be avoided.
Cow<'_, str> strikes a balance between performance and robustness: you don't have to worry about a runtime
error if the field is percent-encoded, but you minimise memory usage when it is.