AppSession

Trait AppSession 

Source
pub trait AppSession: Sized {
    // Required methods
    fn from_db<'life0, 'async_trait>(
        pool: &'life0 PgPool,
        session_id: Uuid,
    ) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn create<'life0, 'async_trait>(
        pool: &'life0 PgPool,
    ) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn from_inner(inner: CJASession) -> Self;
    fn inner(&self) -> &CJASession;

    // Provided methods
    fn session_id(&self) -> &Uuid { ... }
    fn created_at(&self) -> &DateTime<Utc> { ... }
    fn updated_at(&self) -> &DateTime<Utc> { ... }
}
Expand description

A trait for implementing custom session types that integrate with the framework’s session management.

Sessions are automatically created when needed and persisted across requests using secure cookies. Your session type must include the CJASession as an inner field and can add any additional fields needed by your application.

§Example

use cja::server::session::{AppSession, CJASession};
use serde::{Serialize, Deserialize};

#[derive(Debug, Clone)]
struct UserSession {
    inner: CJASession,
    user_id: Option<i32>,
    preferences: serde_json::Value,
}

#[async_trait::async_trait]
impl AppSession for UserSession {
    async fn from_db(pool: &sqlx::PgPool, session_id: uuid::Uuid) -> cja::Result<Self> {
        // Query your session data including any custom fields
        // In a real app, you'd have extended the sessions table with these columns
        let row = sqlx::query_as::<_, CJASession>(
            "SELECT session_id, created_at, updated_at FROM sessions WHERE session_id = $1"
        )
        .bind(session_id)
        .fetch_one(pool)
        .await?;
         
        // For this example, we're just using default values for custom fields
        // In a real app, you'd query your extended session data here
        Ok(Self {
            inner: row,
            user_id: None,
            preferences: serde_json::json!({}),
        })
    }
     
    async fn create(pool: &sqlx::PgPool) -> cja::Result<Self> {
        let row = sqlx::query_as::<_, CJASession>(
            "INSERT INTO sessions DEFAULT VALUES RETURNING session_id, created_at, updated_at"
        )
        .fetch_one(pool)
        .await?;
         
        Ok(Self {
            inner: row,
            user_id: None,
            preferences: serde_json::json!({}),
        })
    }
     
    fn from_inner(inner: CJASession) -> Self {
        Self {
            inner,
            user_id: None,
            preferences: serde_json::json!({}),
        }
    }
     
    fn inner(&self) -> &CJASession {
        &self.inner
    }
}

§Using Sessions in Handlers

use axum::response::IntoResponse;
use cja::server::session::Session;

async fn handler(
    Session(session): Session<UserSession>
) -> impl IntoResponse {
    format!("Session ID: {}, User: {:?}",
            session.session_id(),
            session.user_id)
}

Required Methods§

Source

fn from_db<'life0, 'async_trait>( pool: &'life0 PgPool, session_id: Uuid, ) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Load a session from the database by its ID.

This method should fetch the session record and any associated data from your sessions table.

Source

fn create<'life0, 'async_trait>( pool: &'life0 PgPool, ) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Create a new session in the database.

This method should insert a new session record with default values and return the created session.

Source

fn from_inner(inner: CJASession) -> Self

Create a session instance from the inner CJASession.

This is used internally when reconstructing sessions. Custom fields should be initialized with default values.

Source

fn inner(&self) -> &CJASession

Get a reference to the inner CJASession.

This provides access to the core session fields like ID and timestamps.

Provided Methods§

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.

Implementors§