hyperlite 0.1.0

Lightweight HTTP framework built on hyper, tokio, and tower
Documentation
//! Minimal Hyperlite server showcasing a single JSON endpoint.
//!
//! Run with:
//! ```bash
//! cargo run --example hello_world
//! ```
//!
//! Then visit `http://127.0.0.1:3000/hello` or use curl:
//! ```bash
//! curl http://127.0.0.1:3000/hello
//! ```
//!
//! Expected response:
//! ```json
//! {
//!   "success": true,
//!   "data": { "message": "Hello, World!" },
//!   "meta": { "timestamp": "2024-01-15T10:30:00Z" }
//! }
//! ```

use bytes::Bytes;
use http_body_util::Full;
use hyper::{Method, Request, Response, StatusCode};
use hyperlite::{serve, success, BoxBody, BoxError, Router};
use serde::Serialize;
use std::net::SocketAddr;
use std::sync::Arc;

/// Shared application state. Even though this example doesn't store any data,
/// the struct shows how easily you can add configuration or services later on.
#[derive(Clone)]
struct AppState;

/// JSON payload returned by the `/hello` endpoint.
#[derive(Serialize)]
struct Greeting {
    message: String,
}

/// Example handler demonstrating Hyperlite's handler signature.
async fn hello_handler(
    _req: Request<BoxBody>,
    _state: Arc<AppState>,
) -> Result<Response<Full<Bytes>>, BoxError> {
    let greeting = Greeting {
        message: "Hello, World!".to_string(),
    };
    Ok(success(StatusCode::OK, greeting))
}

#[tokio::main]
async fn main() -> Result<(), BoxError> {
    let state = AppState;
    let router = Router::new(state).route(
        "/hello",
        Method::GET,
        Arc::new(|req, state| Box::pin(hello_handler(req, state))),
    );

    let addr: SocketAddr = "127.0.0.1:3000"
        .parse()
        .expect("valid socket address for example server");
    println!("Server running on http://{addr}/hello");

    serve(addr, router).await
}