pub trait ApiConnExt {
// Required methods
fn with_json(self, response: &impl Serialize) -> Self;
fn deserialize<T>(&mut self) -> impl Future<Output = Result<T>> + Send
where T: DeserializeOwned;
fn deserialize_json<T>(&mut self) -> impl Future<Output = Result<T>> + Send
where T: DeserializeOwned;
fn serialize<T>(
&mut self,
body: &T,
) -> impl Future<Output = Result<()>> + Send
where T: Serialize + Sync;
fn content_type(&self) -> Result<Mime>;
}Expand description
Extension trait that adds api methods to [trillium::Conn]
Required Methods§
Sourcefn with_json(self, response: &impl Serialize) -> Self
Available on crate features serde_json or sonic-rs only.
fn with_json(self, response: &impl Serialize) -> Self
serde_json or sonic-rs only.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};
use trillium_testing::TestServer;
async fn handler(conn: trillium::Conn) -> trillium::Conn {
conn.with_json(&json!({ "json macro": "is reexported" }))
}
let app = TestServer::new(handler).await;
app.get("/")
.await
.assert_ok()
.assert_body(r#"{"json macro":"is reexported"}"#)
.assert_header("content-type", "application/json");§overriding status code
use serde::Serialize;
use trillium_api::ApiConnExt;
use trillium_testing::TestServer;
#[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)
}
let app = TestServer::new(handler).await;
app.get("/")
.await
.assert_status(201)
.assert_body(r#"{"string":"not the most creative example","number":100}"#)
.assert_header("content-type", "application/json");Sourcefn deserialize<T>(&mut self) -> impl Future<Output = Result<T>> + Sendwhere
T: DeserializeOwned,
fn deserialize<T>(&mut self) -> impl Future<Output = Result<T>> + Sendwhere
T: DeserializeOwned,
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.
This sets a status code of Status::Ok if and only if no status code has been explicitly set.
§Examples
§Deserializing to Value
use trillium_api::{ApiConnExt, Value};
async fn handler(mut conn: trillium::Conn) -> trillium::Conn {
let value: Value = match conn.deserialize().await {
Ok(v) => v,
Err(_) => return conn.with_status(400),
};
conn.with_json(&value)
}
let app = TestServer::new(handler).await;
app.post("/")
.with_body(r#"key=value"#)
.with_request_header("content-type", "application/x-www-form-urlencoded")
.await
.assert_ok()
.assert_body(r#"{"key":"value"}"#)
.assert_header("content-type", "application/json");§Deserializing a concrete type
use trillium_api::ApiConnExt;
use trillium_testing::TestServer;
#[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(),
}
}
let app = TestServer::new(handler).await;
app.post("/")
.with_body(r#"key=name&value=trillium"#)
.with_request_header("content-type", "application/x-www-form-urlencoded")
.await
.assert_status(201)
.assert_body(r#"name is trillium"#);
app.post("/")
.with_body(r#"name=trillium"#)
.with_request_header("content-type", "application/x-www-form-urlencoded")
.await
.assert_status(422)
.assert_body(r#"nope"#);Sourcefn deserialize_json<T>(&mut self) -> impl Future<Output = Result<T>> + Sendwhere
T: DeserializeOwned,
Available on crate features serde_json or sonic-rs only.
fn deserialize_json<T>(&mut self) -> impl Future<Output = Result<T>> + Sendwhere
T: DeserializeOwned,
serde_json or sonic-rs only.Deserializes json without any Accepts header content negotiation
Sourcefn serialize<T>(&mut self, body: &T) -> impl Future<Output = Result<()>> + Send
fn serialize<T>(&mut self, body: &T) -> impl Future<Output = Result<()>> + Send
Serializes the provided body using Accepts header content negotiation
Sourcefn content_type(&self) -> Result<Mime>
fn content_type(&self) -> Result<Mime>
Returns a parsed content type for this conn.
Note that this function considers a missing content type an error of variant
Error::MissingContentType.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementations on Foreign Types§
Source§impl ApiConnExt for Conn
impl ApiConnExt for Conn
Source§fn with_json(self, response: &impl Serialize) -> Self
fn with_json(self, response: &impl Serialize) -> Self
serde_json or sonic-rs only.async fn deserialize<T>(&mut self) -> Result<T>where
T: DeserializeOwned,
fn content_type(&self) -> Result<Mime>
Source§async fn deserialize_json<T>(&mut self) -> Result<T>where
T: DeserializeOwned,
async fn deserialize_json<T>(&mut self) -> Result<T>where
T: DeserializeOwned,
serde_json or sonic-rs only.