### Install and Run Rejoice CLI Source: https://github.com/kiahjh/rejoice/blob/master/README.md Commands to install the Rejoice CLI using Cargo and start a new project with or without database support, then launch the development server. ```bash cargo install rejoice rejoice init my-app cd my-app rejoice dev ``` ```bash rejoice init my-app --with-db ``` -------------------------------- ### Enable and Start Systemd Service Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/deployment.md Commands to enable the systemd service to start on boot and to start the service immediately. ```bash sudo systemctl enable my-app sudo systemctl start my-app ``` -------------------------------- ### Install and Use Rejoice CLI Source: https://context7.com/kiahjh/rejoice/llms.txt Commands for installing the Rejoice CLI, creating new projects (with or without database support), running the development server, building for production, and managing database migrations. ```bash cargo install rejoice rejoice init my-app cd my-app rejoice init my-app --with-db rejoice dev rejoice build --release rejoice migrate add create_users_table rejoice migrate up rejoice migrate revert rejoice migrate status ``` -------------------------------- ### Res - Example Usage for HTML and Redirect Responses Source: https://github.com/kiahjh/rejoice/blob/master/AGENTS.md Provides practical examples of using the `Res` type within an async handler function. It demonstrates setting cookies and headers, returning an HTML response with embedded markup, and handling redirects based on request conditions like missing session cookies. ```rust pub async fn get(state: AppState, req: Req, res: Res) -> Res { // Read cookies let session = req.cookies.get("session"); if session.is_none() { // Redirect (bypasses layout wrapping) return res.redirect("/login"); } // Set cookies and return HTML res.set_cookie("last_visit", "2025-01-01") .set_header("X-Custom", "value") .html(html! { h1 { "Dashboard" } }) } // API endpoint returning JSON pub async fn get(state: AppState, req: Req, res: Res) -> Res { let users = get_users(&state.db).await; res.json(&users) } ``` -------------------------------- ### Rejoice File-Based Routing Example Source: https://github.com/kiahjh/rejoice/blob/master/README.md Demonstrates Rejoice's file-based routing structure where `.rs` files in `src/routes/` map to URL paths. It shows how to define a simple GET handler for the root path. ```rust use rejoice::{Req, Res, html}; pub async fn get(req: Req, res: Res) -> Res { res.html(html! { h1 { "Hello, world!" } }) } ``` -------------------------------- ### Start Rejoice Development Server Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/installation.md Launches the Rejoice development server, typically accessible at http://localhost:8080. The server features automatic Rust recompilation, Vite watch mode for client-side assets, and live browser reloading. ```bash rejoice dev ``` -------------------------------- ### Set SQLite Database URL Environment Variable Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Example of setting the `DATABASE_URL` environment variable for SQLite and then running the Rejoice application. This is typically done before starting the application in a production environment. ```bash export DATABASE_URL=sqlite:./my-app.db ./target/release/my-app ``` -------------------------------- ### Example SQL Migration: Create Users Table (SQL) Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/database.md An example SQL script for the `up` migration to create a 'users' table. It defines columns for id, name, email, and creation timestamp, with email being unique. ```sql CREATE TABLE users ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT NOT NULL UNIQUE, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` -------------------------------- ### App Initialization - Stateless Source: https://github.com/kiahjh/rejoice/blob/master/AGENTS.md Shows how to create a new Rejoice application instance for stateless applications. This involves instantiating the `App` with a port number and a generated router. ```rust let app = App::new(8080, create_router()); ``` -------------------------------- ### Application Entry Point (Rust) Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/project-structure.md The main.rs file serves as the application's entry point. It initializes the Rejoice App with a specified port and the generated router, then starts the server. ```rust use rejoice::App; rejoice::routes!(); #[tokio::main] async fn main() { let app = App::new(8080, create_router()); app.run().await; } ``` -------------------------------- ### Static Asset Mapping in Rejoice Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Explains how files in the `public/` directory are served at the root URL in a Rejoice project. Provides examples of file paths and their corresponding URLs. ```markdown | File Path | URL | |-----------|-----| | `public/logo.png` | `/logo.png` | | `public/images/hero.jpg` | `/images/hero.jpg` | | `public/favicon.ico` | `/favicon.ico` | | `public/fonts/custom.woff2` | `/fonts/custom.woff2` | ``` -------------------------------- ### Generate Router with Axum Source: https://github.com/kiahjh/rejoice/blob/master/AGENTS.md Demonstrates the generation of an Axum router using the `create_router` function. This function sets up routes, including a GET route for the index page handled by `wrapper_index`. It utilizes `__RejoiceState` for type hinting. ```rust pub fn create_router() -> axum::Router<__RejoiceState> { axum::Router::new() .route("/", axum::routing::get(wrapper_index)) // ... more routes } ``` -------------------------------- ### App Initialization - Stateful Source: https://github.com/kiahjh/rejoice/blob/master/AGENTS.md Demonstrates the creation of a Rejoice application instance for stateful applications. This method, `App::with_state`, takes a port, a router, and the application state, which must implement `Clone + Send + Sync + 'static`. ```rust let app = App::with_state(8080, create_router(), state); ``` -------------------------------- ### Handle GET and POST for Contact Form in Rust Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Illustrates how a single route file can handle multiple HTTP methods for a contact form. The `get` function displays the form, and the `post` function handles form submission, including validation and processing. Uses `rejoice` for request/response and `serde` for deserialization. ```rust use rejoice::{Req, Res, html}; use serde::Deserialize; #[derive(Deserialize)] struct ContactForm { name: String, email: String, message: String, } // GET /contact - Display the form pub async fn get(req: Req, res: Res) -> Res { res.html(html! { h1 { "Contact Us" } form method="post" { input type="text" name="name" placeholder="Your name" required; input type="email" name="email" placeholder="Your email" required; textarea name="message" placeholder="Your message" required {} button type="submit" { "Send" } } }) } // POST /contact - Handle form submission pub async fn post(req: Req, res: Res) -> Res { let Ok(form) = req.body.as_form::() else { return res.bad_request("Invalid form data"); }; // Process the form (send email, save to database, etc.) println!("Message from {}: {}", form.name, form.message); res.redirect("/thank-you") } ``` -------------------------------- ### Stateful App with SQLite Pool Setup (Rust) Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Configures and initializes a Rejoice application with a SQLite database connection pool. It defines `AppState` to hold the `Pool`, sets up the pool configuration using environment variables, and then runs the application. ```rust use std::time::Duration; use rejoice::{ App, db::{Pool, PoolConfig, Sqlite, create_pool}, }; rejoice::routes!(AppState); #[derive(Clone)] pub struct AppState { pub db: Pool, } #[tokio::main] async fn main() { let pool = create_pool(PoolConfig { db_url: rejoice::env!("DATABASE_URL").to_string(), max_connections: 5, acquire_timeout: Duration::from_secs(3), idle_timeout: Duration::from_secs(60), max_lifetime: Duration::from_secs(1800), }).await; let state = AppState { db: pool }; let app = App::with_state(8080, create_router(), state); app.run().await; } ``` -------------------------------- ### Example SQL Migration: Revert Create Users Table (SQL) Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/database.md An example SQL script for the `down` migration to revert the creation of the 'users' table. It simply drops the table. ```sql DROP TABLE users; ``` -------------------------------- ### Error Handling Examples Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Demonstrates how to return error responses using built-in helpers or custom status codes. ```APIDOC ## Error Handling ### Description Examples of how to handle errors and return appropriate responses. ### Method GET (Illustrative) ### Endpoint (Illustrative) ### Parameters None ### Request Example None ### Response #### Not Found Response (404) Returned when a resource is not found. #### Custom Status Response (e.g., 418 I'm a teapot) Returned for custom error conditions. ### Error Handling Examples #### Example 1: Returning Not Found ```rust use rejoice::{Req, Res, html}; pub async fn get(req: Req, res: Res, id: String) -> Res { let user = fetch_user(&id).await; match user { Ok(user) => res.html(html! { h1 { (user.name) } }), Err(_) => res.not_found("User not found"), } } ``` #### Example 2: Setting Custom Status Code ```rust use rejoice::{Req, Res, html}; use axum::http::StatusCode; pub async fn get(req: Req, res: Res) -> Res { res.set_status(StatusCode::IM_A_TEAPOT) .html(html! { h1 { "I'm a teapot" } }) } ``` ``` -------------------------------- ### App and State Management Source: https://github.com/kiahjh/rejoice/blob/master/AGENTS.md Configuration for creating stateless and stateful applications, and defining route handler signatures. ```APIDOC ## App and State ### Stateless apps ```rust let app = App::new(8080, create_router()); ``` ### Stateful apps ```rust let app = App::with_state(8080, create_router(), state); ``` `App::with_state()` is generic over any `S: Clone + Send + Sync + 'static`. The state is attached to the router via Axum's `.with_state()` before serving. ### Route signatures Routes and layouts receive state as a plain value (not wrapped in `State`): ```rust // Stateless pub async fn get(req: Req, res: Res) -> Res { ... } pub async fn post(req: Req, res: Res) -> Res { ... } pub async fn layout(req: Req, res: Res, children: Children) -> Res { ... } // Stateful pub async fn get(state: AppState, req: Req, res: Res) -> Res { ... } pub async fn post(state: AppState, req: Req, res: Res) -> Res { ... } pub async fn layout(state: AppState, req: Req, res: Res, children: Children) -> Res { ... } ``` Note: The codegen handles Axum's `State` extraction internally; user code receives the unwrapped state value. ``` -------------------------------- ### Database Support Source: https://github.com/kiahjh/rejoice/blob/master/AGENTS.md Information on enabling and using the database module, specifically for SQLite integration. ```APIDOC ## Database Support **Feature-gated:** The database module requires the `sqlite` feature flag. ```toml # In user's Cargo.toml rejoice = { version = "...", features = ["sqlite"] } ``` Exports in `src/db.rs` (only available with `sqlite` feature): - `Pool`, `Sqlite` - sqlx types - `query`, `query_as`, `query_scalar` - sqlx query functions/macros - `FromRow` - Derive macro for mapping query results to structs - `PoolConfig`, `create_pool` - Pool creation helpers Users access via `rejoice::db::*`. When `rejoice init --with-db` is used, the generated `Cargo.toml` automatically includes the `sqlite` feature. ``` -------------------------------- ### Build Rejoice Project for Production Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/installation.md Compiles and optimizes the Rejoice application for deployment. This command generates a release binary in 'target/release/' and compiles client assets into the 'dist/' directory. ```bash rejoice build --release ``` -------------------------------- ### Prelude Module Usage (Rust) Source: https://github.com/kiahjh/rejoice/blob/master/AGENTS.md This Rust code demonstrates how to use the `prelude` module to bring common Rejoice framework items into scope with a single `use` statement. This simplifies the import process for developers working with the framework. ```rust use rejoice::prelude::*; // Now you can use items like App, Req, Res, etc. directly fn my_handler(req: Req) -> Res { // ... handler logic ... Res::new() } ``` -------------------------------- ### Run Compiled Rejoice Binary Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/deployment.md Executes the compiled Rejoice application binary. It's crucial to run this from the project root where 'dist/' and 'public/' directories reside, or after copying all necessary files to a deployment directory. ```bash cd /path/to/my-app ./target/release/my-app ``` ```bash mkdir deploy cp target/release/my-app deploy/ cp -r dist deploy/ cp -r public deploy/ cp .env deploy/ # if using database cd deploy ./my-app ``` -------------------------------- ### Redirecting in Rust Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt This code snippet demonstrates how to perform redirects using the Rejoice framework. It shows examples of both temporary (302 Found) and permanent (301 Moved Permanently) redirects. ```rust use rejoice::{Req, Res}; pub async fn get(req: Req, res: Res) -> Res { // Temporary redirect (302 Found) res.redirect("/login") } pub async fn get(req: Req, res: Res) -> Res { // Permanent redirect (301 Moved Permanently) res.redirect_permanent("/new-url") } ``` -------------------------------- ### Dockerfile for Rejoice Application Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/deployment.md A multi-stage Dockerfile for building and deploying a Rejoice application. It uses a Rust builder image to compile the application and a slim Debian image for the final runtime environment. ```dockerfile FROM rust:1.85 AS builder WORKDIR /app COPY . . RUN cargo build --release -p my-app FROM debian:bookworm-slim WORKDIR /app COPY --from=builder /app/target/release/my-app . COPY dist/ dist/ COPY public/ public/ EXPOSE 8080 CMD ["./my-app"] ``` -------------------------------- ### Enabling SQLite Database Support Source: https://github.com/kiahjh/rejoice/blob/master/AGENTS.md Explains how to enable database support, specifically SQLite, in a Rejoice project. This is achieved by adding the `sqlite` feature flag to the `rejoice` dependency in the `Cargo.toml` file. ```toml # In user's Cargo.toml rejoice = { version = "...", features = ["sqlite"] } ``` -------------------------------- ### Import Rejoice Database Module (Feature-Gated) Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Imports the database module for interacting with databases, specifically SQLite in this example. This module requires the 'sqlite' feature to be enabled in the project's Cargo.toml. It provides types for connection pooling, querying, and data mapping. ```rust use rejoice::db::{ Pool, // sqlx Pool type Sqlite, // SQLite driver type query, // Raw SQL query query_as, // Typed SQL query query_scalar, // Scalar SQL query (COUNT, MAX, etc.) FromRow, // Derive macro for result mapping PoolConfig, // Pool configuration create_pool, // Pool creation function }; ``` -------------------------------- ### Build and Deploy Rejoice Application (Bash) Source: https://context7.com/kiahjh/rejoice/llms.txt This snippet demonstrates how to build an optimized release binary for a Rejoice application using the `rejoice build --release` command. It lists the essential files required for deployment and shows how to run the application directly or copy it to a deployment directory. ```bash # Build optimized release binary rejoice build --release # Required files for deployment # - target/release/my-app (binary) # - dist/ (compiled JS/CSS) # - public/ (static assets) # - .env (if using database) # - my-app.db (SQLite database file) # Run the binary from project root ./target/release/my-app # Or copy to deployment directory mkdir -p /var/www/my-app cp target/release/my-app /var/www/my-app/ cp -r dist public .env /var/www/my-app/ cd /var/www/my-app && ./my-app ``` -------------------------------- ### Implement File-Based Routing in Rust Source: https://context7.com/kiahjh/rejoice/llms.txt Demonstrates how to set up routes using `.rs` files in the `src/routes/` directory. Includes examples for root paths, dynamic route parameters, and handling multiple HTTP methods within a single file. ```rust // src/routes/index.rs -> GET / use rejoice::{Req, Res, html}; pub async fn get(req: Req, res: Res) -> Res { res.html(html! { h1 { "Hello, World!" } }) } // src/routes/about.rs -> GET /about pub async fn get(req: Req, res: Res) -> Res { res.html(html! { h1 { "About Us" } p { "Welcome to our site." } }) } // src/routes/users/[id].rs -> GET /users/:id pub async fn get(req: Req, res: Res, id: String) -> Res { res.html(html! { h1 { "User Profile" } p { "User ID: " (id) } }) } // Multiple HTTP methods in one file pub async fn post(req: Req, res: Res) -> Res { res.redirect("/success") } ``` -------------------------------- ### Dockerfile for Rejoice Application Deployment Source: https://context7.com/kiahjh/rejoice/llms.txt This Dockerfile example sets up a multi-stage build process for deploying a Rejoice application. It first builds the release binary using a Rust image and then copies the compiled binary, static assets, and public files into a slim Debian image for a smaller final container. ```dockerfile # Dockerfile example FROM rust:1.85 AS builder WORKDIR /app COPY . . RUN cargo build --release -p my-app FROM debian:bookworm-slim WORKDIR /app COPY --from=builder /app/target/release/my-app . COPY dist/ dist/ COPY public/ public/ EXPOSE 8080 CMD ["./my-app"] ``` -------------------------------- ### Read Runtime Environment Variables in Rust Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/deployment.md Shows how to read environment variables at runtime in Rust using `std::env`. This example retrieves the 'PORT' variable, defaults to '8080' if not set, and parses it into a u16. ```rust let port: u16 = std::env::var("PORT") .unwrap_or_else(|_| "8080".to_string()) .parse() .unwrap(); let app = App::new(port, create_router()); ``` -------------------------------- ### Nginx Reverse Proxy Configuration Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/deployment.md An example Nginx configuration to act as a reverse proxy for a Rejoice application. It listens on port 80, forwards requests to the app running on 'http://127.0.0.1:8080', and sets necessary headers. ```nginx server { listen 80; server_name example.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` -------------------------------- ### Body Methods in Rust Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt This code snippet provides examples of methods available for working with the request body in the Rejoice framework. It shows how to check if the body is empty, get the raw bytes, parse the body as UTF-8 text, parse as JSON into a typed struct, and parse as form data. ```rust // Check if body is empty req.body.is_empty() // Get raw bytes req.body.as_bytes() // Parse as UTF-8 text req.body.as_text() -> Result // Parse as JSON into typed struct req.body.as_json::() -> Result // Parse as form data (application/x-www-form-urlencoded) req.body.as_form::() -> Result ``` -------------------------------- ### Req - Incoming Request Structure and Usage Source: https://github.com/kiahjh/rejoice/blob/master/AGENTS.md Defines the `Req` struct for incoming HTTP requests, providing access to headers, cookies, method, URI, and body. It includes examples of reading request data like headers and cookies, and parsing the request body as form data or JSON. ```rust pub struct Req { pub headers: HeaderMap, pub cookies: Cookies, pub method: Method, pub uri: Uri, pub body: Body, } // Reading request data let auth = req.headers.get("Authorization"); let session = req.cookies.get("session_id"); // Parsing POST body let form = req.body.as_form::()?; let json = req.body.as_json::()?; ``` -------------------------------- ### Configuring Rejoice App (Stateless and Stateful) Source: https://context7.com/kiahjh/rejoice/llms.txt Illustrates how to configure and run a Rejoice web application. It covers creating a stateless app using `App::new()` and a stateful app with shared state using `App::with_state()`, including custom configurations for database pools and API keys. ```rust // Stateless app (src/main.rs) use rejoice::App; rejoice::routes!(); #[tokio::main] async fn main() { let app = App::new(8080, create_router()); app.run().await; } ``` ```rust // Stateful app with custom configuration use std::time::Duration; use rejoice::{App, db::{Pool, PoolConfig, Sqlite, create_pool}}; #[derive(Clone)] pub struct AppState { pub db: Pool, pub api_key: String, } rejoice::routes!(AppState); #[tokio::main] async fn main() { let pool = create_pool(PoolConfig { db_url: rejoice::env!("DATABASE_URL").to_string(), max_connections: 10, acquire_timeout: Duration::from_secs(5), idle_timeout: Duration::from_secs(300), max_lifetime: Duration::from_secs(3600), }).await; let state = AppState { db: pool, api_key: std::env::var("API_KEY").unwrap_or_default(), }; let port: u16 = std::env::var("PORT") .unwrap_or_else(|_| "8080".to_string()) .parse() .unwrap(); let app = App::with_state(port, create_router(), state); app.run().await; } ``` -------------------------------- ### Live Reload WebSocket Server (Rust) Source: https://github.com/kiahjh/rejoice/blob/master/AGENTS.md This snippet outlines the setup of a WebSocket server for live reloading, typically running on port 3001 at the `/__reload` endpoint. This server is crucial for the Hot Module Replacement (HMR) feature, allowing the client to receive notifications about file changes and trigger reloads. ```rust // Located in dev.rs // Conceptual representation of starting a WebSocket server use tokio::net::TcpListener; use futures_util::stream::StreamExt; async fn start_reload_server() -> Result<(), Box> { let listener = TcpListener::bind("127.0.0.1:3001").await?; println!("Live reload server started on ws://127.0.0.1:3001/__reload"); // Accept incoming connections and handle them // ... WebSocket handling logic ... Ok(()) } ``` -------------------------------- ### Create a New Rejoice Project Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/installation.md Initializes a new Rejoice project named 'my-app'. This command sets up a standard project structure including Rust source files, Vite configuration, Tailwind CSS, and a SolidJS island component. ```bash rejoice init my-app cd my-app ``` -------------------------------- ### Rust Server-Rendered Page Example Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/introduction.md This Rust code snippet demonstrates a basic server-rendered page in Rejoice. It defines an async function that handles GET requests and returns an HTML response using Rejoice's `html!` macro. The function takes a `Req` and `Res` object and returns a `Res` object. ```rust use rejoice::{Req, Res, html}; pub async fn get(req: Req, res: Res) -> Res { res.html(html! { h1 { "Hello from Rejoice!" } p { "This is a server-rendered page." } }) } ``` -------------------------------- ### Set up Stateful Rejoice Application Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Configures and runs a stateful Rejoice web application. It defines routes with a state type using `rejoice::routes!(AppState)` and initializes the application with shared state using `App::with_state`. The state must be `Clone`. ```rust use rejoice::App; rejoice::routes!(AppState); #[derive(Clone)] pub struct AppState { /* ... */ } #[tokio::main] async fn main() { let state = AppState { /* ... */ }; let app = App::with_state(8080, create_router(), state); app.run().await; } ``` -------------------------------- ### Res - Response Builder Mutators and Finalizers Source: https://github.com/kiahjh/rejoice/blob/master/AGENTS.md Details the `Res` type, a response builder utilizing interior mutability. It outlines mutator methods for setting cookies, headers, and status codes, and finalizer methods for generating different response types like HTML, JSON, redirects, and raw bytes. Examples show chaining mutators and creating responses. ```rust // Mutators (return `&Res` for chaining): // `set_cookie(name, value)` // `set_cookie_with_options(...)` // `delete_cookie(name)` // `set_header(name, value)` // `set_status(StatusCode)` // Finalizers (take `&self`, return owned `Res` - chainable from mutators): // `html(Markup)` // `json(&impl Serialize)` // `redirect(url)` // `redirect_permanent(url)` // `raw(impl Into>)` ``` -------------------------------- ### Create a New Rejoice Project with Database Support Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/installation.md Initializes a new Rejoice project with integrated SQLite database support. This option automatically configures a .env file with DATABASE_URL, creates an empty SQLite database, and sets up the AppState struct with a connection pool. ```bash rejoice init my-app --with-db ``` -------------------------------- ### Install Rejoice CLI using Cargo Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/installation.md Installs the Rejoice Command Line Interface globally using the Cargo package manager. This command provides access to all Rejoice project management functionalities. ```bash cargo install rejoice ``` -------------------------------- ### HTTP Method Handlers (Rust) Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Defines asynchronous functions for handling GET and POST requests. These functions take a request (Req) and response (Res) object and return a response. The GET handler renders HTML, while the POST handler demonstrates a redirect. ```rust use rejoice::{Req, Res, html}; // GET request handler pub async fn get(req: Req, res: Res) -> Res { res.html(html! { h1 { "Hello, World!" } }) } // POST request handler pub async fn post(req: Req, res: Res) -> Res { // Handle form submission, API call, etc. res.redirect("/success") } ``` -------------------------------- ### Rejoice Database Integration with SQLx Source: https://github.com/kiahjh/rejoice/blob/master/README.md Shows how to set up and use SQLite database support in Rejoice projects initialized with `--with-db`. It demonstrates querying data and rendering it within a route handler. ```rust use crate::AppState; use rejoice::{Req, Res, db::query_as, html}; pub async fn get(state: AppState, req: Req, res: Res) -> Res { let users: Vec<(String,)> = query_as("SELECT name FROM users") .fetch_all(&state.db) .await .unwrap(); res.html(html! { h1 { "Users" } ul { @for user in &users { li { (user.0) } } } }) } ``` -------------------------------- ### Blog Index Page with Post List Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Renders the index page for a blog, displaying a list of posts. It uses the `html!` macro to generate the HTML structure, iterating over a vector of post titles and excerpts. Each post is displayed in an `article` element with specific styling. ```rust use rejoice::{Req, Res, html}; pub async fn get(req: Req, res: Res) -> Res { let posts = vec![ ("Hello World", "My first post"), ("Rust is Great", "Why I love Rust"), ]; res.html(html! { h1 class="text-3xl font-bold mb-4" { "Latest Posts" } @for (title, excerpt) in &posts { article class="bg-white p-4 rounded shadow mb-4" { h2 class="text-xl font-semibold" { (title) } p class="text-gray-600" { (excerpt) } } } }) } ``` -------------------------------- ### API Endpoint: Get Users Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Retrieves a list of all users from the database, including their ID, name, and email. ```APIDOC ## GET /api/users ### Description Fetches a list of all users from the database. Includes caching for 60 seconds. ### Method GET ### Endpoint /api/users ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) JSON object containing a list of users and their count. #### Response Example ```json { "users": [ { "id": 1, "name": "John Doe", "email": "john.doe@example.com" }, { "id": 2, "name": "Jane Smith", "email": "jane.smith@example.com" } ], "count": 2 } ``` ``` -------------------------------- ### Database Querying with Rejoice (Rust) Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Demonstrates how to perform various database operations using Rejoice's `query` and `query_as` functions. It includes fetching typed results, fetching optional results with parameters, and executing insert/update/delete statements. The `FromRow` derive macro is used for mapping results to structs. ```rust use crate::AppState; use rejoice::{Req, Res, html, db::{query, query_as, FromRow}}; #[derive(FromRow)] struct User { id: i32, name: String, email: String, } pub async fn get(state: AppState, req: Req, res: Res) -> Res { // Query with query_as (returns typed results) let users: Vec = query_as("SELECT id, name, email FROM users") .fetch_all(&state.db) .await .unwrap(); // Query with parameters let user: Option = query_as("SELECT * FROM users WHERE id = ?") .bind(123) .fetch_optional(&state.db) .await .unwrap(); // Insert/Update/Delete query("INSERT INTO users (name, email) VALUES (?, ?)") .bind("Alice") .bind("alice@example.com") .execute(&state.db) .await .unwrap(); res.html(html! { h1 { "Users" } ul { @for user in &users { li { (user.name) " - " (user.email) } } } }) } ``` -------------------------------- ### Run Production Binary Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Command to execute the compiled Rejoice application binary. It should be run from the project root directory to ensure correct asset loading. ```bash ./target/release/my-app ``` -------------------------------- ### Stateful App Initialization (Rust) Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Initializes a Rejoice application with shared state, such as a database connection pool and configuration. The `AppState` struct must implement `Clone`, `Send`, `Sync`, and `'static`. This allows the application to manage and access shared resources across requests. ```rust use rejoice::App; rejoice::routes!(AppState); #[derive(Clone)] pub struct AppState { pub db: Pool, pub config: AppConfig, } #[tokio::main] async fn main() { let state = AppState { db: create_pool(/* ... */).await, config: load_config(), }; let app = App::with_state(8080, create_router(), state); app.run().await; } ``` -------------------------------- ### Reading Request Method and URI Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Shows how to get the HTTP method, request path, and query string from the request URI. ```APIDOC ## GET /request-info ### Description This endpoint retrieves and displays the HTTP method, request path, and query parameters. ### Method GET ### Endpoint /request-info ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **method** (string) - The HTTP method of the request (e.g., "GET"). - **path** (string) - The requested path (e.g., "/users/123"). - **query** (string) - The query string, if present (e.g., "page=2&sort=name"). #### Response Example ```html

Method: GET

Path: /request-info

``` ``` -------------------------------- ### Set up Database Connection URL (Text) Source: https://github.com/kiahjh/rejoice/blob/master/docs/content/database.md Defines the connection string for the SQLite database in the .env file. This variable is used by Rejoice to establish a connection to the database. ```text DATABASE_URL=sqlite:./my-app.db ``` -------------------------------- ### Request and Response Types Source: https://github.com/kiahjh/rejoice/blob/master/AGENTS.md Details on the `Req` and `Res` types used for handling incoming requests and building outgoing responses. ```APIDOC ## Request and Response Types ### `Req` - Incoming Request The `Req` type provides access to request data including body: ```rust pub struct Req { pub headers: HeaderMap, // HTTP headers pub cookies: Cookies, // Parsed cookies pub method: Method, // GET, POST, etc. pub uri: Uri, // Request URI pub body: Body, // Request body (for POST, PUT, etc.) } // Reading request data let auth = req.headers.get("Authorization"); let session = req.cookies.get("session_id"); // Parsing POST body let form = req.body.as_form::()?; let json = req.body.as_json::()?; ``` ### `Res` - Response Builder The `Res` type uses interior mutability for building responses. **Mutators** (return `&Res` for chaining): - `set_cookie(name, value)` - Set a cookie - `set_cookie_with_options(...)` - Set cookie with path, max_age, etc. - `delete_cookie(name)` - Delete a cookie - `set_header(name, value)` - Set a response header - `set_status(StatusCode)` - Override status code **Finalizers** (take `&self`, return owned `Res` - chainable from mutators): - `html(Markup)` - HTML response (200, text/html) - `json(&impl Serialize)` - JSON response (200, application/json) - `redirect(url)` - 302 redirect - `redirect_permanent(url)` - 301 redirect - `raw(impl Into>)` - Raw bytes **Example usage:** ```rust pub async fn get(state: AppState, req: Req, res: Res) -> Res { // Read cookies let session = req.cookies.get("session"); if session.is_none() { // Redirect (bypasses layout wrapping) return res.redirect("/login"); } // Set cookies and return HTML res.set_cookie("last_visit", "2025-01-01") .set_header("X-Custom", "value") .html(html! { h1 { "Dashboard" } }) } // API endpoint returning JSON pub async fn get(state: AppState, req: Req, res: Res) -> Res { let users = get_users(&state.db).await; res.json(&users) } ``` **Error helpers:** ```rust res.bad_request("Invalid input") // 400 res.unauthorized("Please log in") // 401 res.forbidden("Access denied") // 403 res.not_found("Page not found") // 404 res.internal_error("Server error") // 500 ``` ``` -------------------------------- ### Serve Raw PDF Response in Rust Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Demonstrates how to send a raw PDF file as a response using the Rejoice framework. It sets the appropriate Content-Type and Content-Disposition headers before sending the PDF bytes. ```rust use rejoice::{Req, Res}; pub async fn get(req: Req, res: Res) -> Res { let pdf_bytes = get_pdf_data(); res.set_header("Content-Type", "application/pdf") .set_header("Content-Disposition", "attachment; filename=\"report.pdf\"") .raw(pdf_bytes) } ``` -------------------------------- ### Custom CSS with Tailwind in Rejoice Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Demonstrates adding custom CSS rules alongside Tailwind CSS in the `client/styles.css` file. This example adds a `custom-gradient` class. ```css @import "tailwindcss"; @source "../src/**/*.rs"; @source "./**/*.tsx"; /* Custom styles */ .custom-gradient { background: linear-gradient(to right, #3b82f6, #8b5cf6); } ``` -------------------------------- ### Reading Method and URI in Rust Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt This code snippet demonstrates how to access the HTTP method, path, and query parameters of a request using the Rejoice framework. It retrieves the method as a string, the path, and the query string. The example then displays the method and path within an HTML response. ```rust use rejoice::{Req, Res, html}; pub async fn get(req: Req, res: Res) -> Res { let method = req.method.as_str(); // "GET", "POST", etc. let path = req.uri.path(); // "/users/123" let query = req.uri.query(); // Some("page=2&sort=name") res.html(html! { p { "Method: " (method) } p { "Path: " (path) } }) } ``` -------------------------------- ### Layout Bypass Example (Rust) Source: https://github.com/kiahjh/rejoice/blob/master/llms-full.txt Demonstrates how non-HTML responses, such as redirects, automatically bypass layout wrapping in Rejoice. This is useful for actions like authentication redirects or API responses. ```rust pub async fn get(req: Req, res: Res) -> Res { if !is_authenticated(&req) { // This redirect is NOT wrapped in layouts return res.redirect("/login"); } // This HTML IS wrapped in layouts res.html(html! { h1 { "Dashboard" } }) } ``` -------------------------------- ### Create Nested Layouts in Rust Source: https://context7.com/kiahjh/rejoice/llms.txt Shows how to implement root and nested layouts using `layout.rs` files. Layouts wrap page content with shared UI elements like navigation and footers, and can include logic such as authentication checks. ```rust // src/routes/layout.rs - Root layout wrapping all pages use rejoice::{Children, Req, Res, html, DOCTYPE}; pub async fn layout(req: Req, res: Res, children: Children) -> Res { res.html(html! { (DOCTYPE) html { head { meta charset="utf-8"; title { "My App" } } body { nav { a href="/" { "Home" } a href="/about" { "About" } a href="/dashboard" { "Dashboard" } } main { (children) } footer { "Built with Rejoice" } } } }) } // src/routes/dashboard/layout.rs - Nested layout for /dashboard/* pub async fn layout(req: Req, res: Res, children: Children) -> Res { // Check authentication in layout let session = req.cookies.get("session_id"); if session.is_none() { return res.redirect("/login"); } res.html(html! { div class="dashboard-layout" { aside class="sidebar" { a href="/dashboard" { "Overview" } a href="/dashboard/settings" { "Settings" } } main { (children) } } }) } ```