Trait ApiConnExt

Source
pub trait ApiConnExt {
    // Required methods
    fn with_json(self, response: &impl Serialize) -> Self;
    fn deserialize<'life0, 'async_trait, T>(
        &'life0 mut self,
    ) -> Pin<Box<dyn Future<Output = Result<T>> + Send + 'async_trait>>
       where T: DeserializeOwned + 'async_trait,
             Self: 'async_trait,
             'life0: 'async_trait;
    fn deserialize_json<'life0, 'async_trait, T>(
        &'life0 mut self,
    ) -> Pin<Box<dyn Future<Output = Result<T>> + Send + 'async_trait>>
       where T: DeserializeOwned + 'async_trait,
             Self: 'async_trait,
             'life0: 'async_trait;
    fn serialize<'life0, 'life1, 'async_trait, T>(
        &'life0 mut self,
        body: &'life1 T,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where T: Serialize + Sync + 'async_trait,
             Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn content_type(&self) -> Result<Mime>;
}
Expand description

Extension trait that adds api methods to [trillium::Conn]

Required Methods§

Source

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)
}

assert_response!(
    get("/").on(&handler),
    Status::Created,
    r#"{"string":"not the most creative example","number":100}"#,
    "content-type" => "application/json"
);
Source

fn deserialize<'life0, 'async_trait, T>( &'life0 mut self, ) -> Pin<Box<dyn Future<Output = Result<T>> + Send + 'async_trait>>
where T: DeserializeOwned + 'async_trait, Self: 'async_trait, 'life0: '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.

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 = 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"#,
);

Source

fn deserialize_json<'life0, 'async_trait, T>( &'life0 mut self, ) -> Pin<Box<dyn Future<Output = Result<T>> + Send + 'async_trait>>
where T: DeserializeOwned + 'async_trait, Self: 'async_trait, 'life0: 'async_trait,

Deserializes json without any Accepts header content negotiation

Source

fn serialize<'life0, 'life1, 'async_trait, T>( &'life0 mut self, body: &'life1 T, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where T: Serialize + Sync + 'async_trait, Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Serializes the provided body using Accepts header content negotiation

Source

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

Source§

fn with_json(self, response: &impl Serialize) -> Self

Source§

fn deserialize<'life0, 'async_trait, T>( &'life0 mut self, ) -> Pin<Box<dyn Future<Output = Result<T>> + Send + 'async_trait>>
where T: DeserializeOwned + 'async_trait, Self: 'async_trait, 'life0: 'async_trait,

Source§

fn content_type(&self) -> Result<Mime>

Source§

fn deserialize_json<'life0, 'async_trait, T>( &'life0 mut self, ) -> Pin<Box<dyn Future<Output = Result<T>> + Send + 'async_trait>>
where T: DeserializeOwned + 'async_trait, Self: 'async_trait, 'life0: 'async_trait,

Source§

fn serialize<'life0, 'life1, 'async_trait, T>( &'life0 mut self, body: &'life1 T, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where T: Serialize + Sync + 'async_trait, Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Implementors§