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 sonic-rs or serde_json only.
fn with_json(self, response: &impl Serialize) -> Self
sonic-rs or serde_json 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 sonic-rs or serde_json only.
fn deserialize_json<T>(&mut self) -> impl Future<Output = Result<T>> + Sendwhere
T: DeserializeOwned,
sonic-rs or serde_json 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", so this trait is not object safe.
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
sonic-rs or serde_json 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,
sonic-rs or serde_json only.