pub trait RequestPayloadExt {
// Required methods
fn payload<D>(&self) -> Result<Option<D>, PayloadError>
where D: DeserializeOwned;
fn json<D>(&self) -> Result<Option<D>, JsonPayloadError>
where D: DeserializeOwned;
fn form_url_encoded<D>(
&self,
) -> Result<Option<D>, FormUrlEncodedPayloadError>
where D: DeserializeOwned;
}
Expand description
Extends http::Request<Body>
with payload deserialization helpers.
Required Methods§
Sourcefn payload<D>(&self) -> Result<Option<D>, PayloadError>where
D: DeserializeOwned,
fn payload<D>(&self) -> Result<Option<D>, PayloadError>where
D: DeserializeOwned,
Return the result of a payload parsed into a type that implements serde::Deserialize
Currently only application/x-www-form-urlencoded
and application/json
flavors of content type
are supported
A PayloadError
will be returned for undeserializable payloads.
If no body is provided, the content-type header is missing,
or the content-type header is unsupported, then Ok(None)
will
be returned. Note that a blank body (e.g. an empty string) is treated
like a present payload by some deserializers and may result in an error.
§Examples
A request’s body can be deserialized if its correctly encoded as per
the request’s Content-Type
header. The two supported content types are
application/x-www-form-urlencoded
and application/json
.
The following handler will work an http request body of x=1&y=2
as well as {"x":1, "y":2}
respectively.
use lambda_http::{
service_fn, Body, Context, Error, IntoResponse, Request, RequestPayloadExt, Response,
};
use serde::Deserialize;
#[derive(Debug, Default, Deserialize)]
struct Args {
#[serde(default)]
x: usize,
#[serde(default)]
y: usize
}
#[tokio::main]
async fn main() -> Result<(), Error> {
lambda_http::run(service_fn(add)).await?;
Ok(())
}
async fn add(
request: Request
) -> Result<Response<Body>, Error> {
let args: Args = request.payload()
.unwrap_or_else(|_parse_err| None)
.unwrap_or_default();
Ok(
Response::new(
format!(
"{} + {} = {}",
args.x,
args.y,
args.x + args.y
).into()
)
)
}
Sourcefn json<D>(&self) -> Result<Option<D>, JsonPayloadError>where
D: DeserializeOwned,
fn json<D>(&self) -> Result<Option<D>, JsonPayloadError>where
D: DeserializeOwned,
Attempts to deserialize the request payload as JSON. When there is no payload,
Ok(None)
is returned.
§Errors
If a present payload is not a valid JSON payload matching the annotated type,
a JsonPayloadError
is returned.
§Examples
§1. Parsing a JSONString.
let req = http::Request::builder()
.body(Body::from("\"I am a JSON string\""))
.expect("failed to build request");
match req.json::<String>() {
Ok(Some(json)) => assert_eq!(json, "I am a JSON string"),
Ok(None) => panic!("payload is missing."),
Err(err) => panic!("error processing json: {err:?}"),
}
§2. Parsing a JSONObject.
#[derive(Deserialize, Eq, PartialEq, Debug)]
struct Person {
name: String,
age: u8,
}
let req = http::Request::builder()
.body(Body::from(r#"{"name": "Adam", "age": 23}"#))
.expect("failed to build request");
match req.json::<Person>() {
Ok(Some(person)) => assert_eq!(
person,
Person {
name: "Adam".to_string(),
age: 23
}
),
Ok(None) => panic!("payload is missing"),
Err(JsonPayloadError::Parsing(err)) => {
if err.is_data() {
panic!("payload does not match Person schema: {err:?}")
}
if err.is_syntax() {
panic!("payload is invalid json: {err:?}")
}
panic!("failed to parse json: {err:?}")
}
}
Sourcefn form_url_encoded<D>(&self) -> Result<Option<D>, FormUrlEncodedPayloadError>where
D: DeserializeOwned,
fn form_url_encoded<D>(&self) -> Result<Option<D>, FormUrlEncodedPayloadError>where
D: DeserializeOwned,
Attempts to deserialize the request payload as an application/x-www-form-urlencoded
content type. When there is no payload, Ok(None)
is returned.
§Errors
If a present payload is not a valid application/x-www-form-urlencoded payload
matching the annotated type, a FormUrlEncodedPayloadError
is returned.
§Examples
let req = http::Request::builder()
.body(Body::from("name=Adam&age=23"))
.expect("failed to build request");
match req.form_url_encoded::<Person>() {
Ok(Some(person)) => assert_eq!(
person,
Person {
name: "Adam".to_string(),
age: 23
}
),
Ok(None) => panic!("payload is missing."),
Err(err) => panic!("error processing payload: {err:?}"),
}
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.