Trait trillium_api::ApiConnExt
source · [−]pub trait ApiConnExt {
fn with_json(self, response: &impl Serialize) -> Self;
fn deserialize<'life0, 'async_trait, T>(
&'life0 mut self
) -> Pin<Box<dyn Future<Output = Result<T, Value>> + Send + 'async_trait>>
where
T: DeserializeOwned,
T: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait;
}
Expand description
Extension trait that adds api methods to [trillium::Conn
]
Required Methods
sourcefn with_json(self, response: &impl Serialize) -> Self
fn with_json(self, response: &impl Serialize) -> Self
Sends a json response body. This sets a status code of 200,
serializes the body with serde_json, sets the content-type to
application/json, and halts the
conn. If serialization fails, a 500 status code is sent as per
[trillium::conn_try
]
Examples
use trillium_api::{json, ApiConnExt};
async fn handler(conn: trillium::Conn) -> trillium::Conn {
conn.with_json(&json!({ "json macro": "is reexported" }))
}
assert_ok!(
get("/").on(&handler),
r#"{"json macro":"is reexported"}"#,
"content-type" => "application/json"
);
overriding status code
use trillium_api::ApiConnExt;
use serde::Serialize;
#[derive(Serialize)]
struct ApiResponse {
string: &'static str,
number: usize
}
async fn handler(conn: trillium::Conn) -> trillium::Conn {
conn.with_json(&ApiResponse { string: "not the most creative example", number: 100 })
.with_status(201) // note that this has to be chained _after_ the with_json call
}
assert_response!(
get("/").on(&handler),
Status::Created,
r#"{"string":"not the most creative example","number":100}"#,
"content-type" => "application/json"
);
sourcefn deserialize<'life0, 'async_trait, T>(
&'life0 mut self
) -> Pin<Box<dyn Future<Output = Result<T, Value>> + Send + 'async_trait>>where
T: DeserializeOwned,
T: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
fn deserialize<'life0, 'async_trait, T>(
&'life0 mut self
) -> Pin<Box<dyn Future<Output = Result<T, Value>> + Send + 'async_trait>>where
T: DeserializeOwned,
T: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
Attempts to deserialize a type from the request body, based on the request content type.
By default, both application/json and application/x-www-form-urlencoded are supported, and future versions may add accepted request content types. Please open an issue if you need to accept another content type.
To exclusively accept application/json, disable default features on this crate.
Examples
Deserializing to Value
use trillium_api::{ApiConnExt, Value};
async fn handler(mut conn: trillium::Conn) -> trillium::Conn {
let value: Value = trillium::conn_try!(conn.deserialize().await, conn);
conn.with_json(&value)
}
assert_ok!(
post("/")
.with_request_body(r#"key=value"#)
.with_request_header("content-type", "application/x-www-form-urlencoded")
.on(&handler),
r#"{"key":"value"}"#,
"content-type" => "application/json"
);
Deserializing a concrete type
use trillium_api::ApiConnExt;
#[derive(serde::Deserialize)]
struct KvPair { key: String, value: String }
async fn handler(mut conn: trillium::Conn) -> trillium::Conn {
match conn.deserialize().await {
Ok(KvPair { key, value }) => {
conn.with_status(201)
.with_body(format!("{} is {}", key, value))
.halt()
}
Err(_) => conn.with_status(422).with_body("nope").halt()
}
}
assert_response!(
post("/")
.with_request_body(r#"key=name&value=trillium"#)
.with_request_header("content-type", "application/x-www-form-urlencoded")
.on(&handler),
Status::Created,
r#"name is trillium"#,
);
assert_response!(
post("/")
.with_request_body(r#"name=trillium"#)
.with_request_header("content-type", "application/x-www-form-urlencoded")
.on(&handler),
Status::UnprocessableEntity,
r#"nope"#,
);