Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Quick Start

Add Dependency

[dependencies]
afast = { version = "0.1.24", features = ["http", "ordinary-http", "ts"] }
tokio = { version = "1", features = ["full"] }

Define State and Handlers

#![allow(unused)]
fn main() {
use afast::{AFast, handler, service, State, Data, Custom, Result};
use afast::{AFastDeserialize, AFastSerialize, Tag};
use std::sync::{Arc, Mutex};

// State — no Clone required, holds &'static T internally
struct AppState {
    db_url: String,
    counter: Arc<Mutex<u64>>,
}

#[derive(AFastDeserialize, Tag)]
#[tag("Auth info")]
struct AuthCustom { token: i64, platform: String }

#[derive(AFastDeserialize, Tag)]
#[tag("Request body")]
struct HelloReq { name: String }

#[derive(AFastSerialize, Tag)]
#[tag("Response body")]
struct HelloResp { message: String }

#[handler(desc("Say hello"), name("hello"))]
async fn hello(
    state: State<AppState>,
    auth: Custom<AuthCustom>,
    req: Data<HelloReq>,
) -> Result<HelloResp> {
    let mut count = state.counter.lock().unwrap();
    *count += 1;
    Ok(HelloResp { message: format!("Hello, {}! (count: {})", req.name, count) })
}
}

Register Routes and Run

#[tokio::main]
async fn main() {
    let svc = service!("api", "Example API" => {
        h(hello),
    });

    AFast::new()
        .state(AppState {
            db_url: "localhost".into(),
            counter: Arc::new(Mutex::new(0)),
        })
        .service(svc)
        .http("0.0.0.0:5000")
        .run().await.unwrap();
}

Run

cargo run
  • HTTP API: POST http://localhost:5000/_api (binary protocol)
  • API Docs: http://localhost:5000/doc
  • Generated TS client: ./client/api.ts

Multiple Transports

#![allow(unused)]
fn main() {
AFast::new()
    .state(app_state)
    .service(svc)
    .ws("0.0.0.0:3001")     // Binary WebSocket
    .tcp("0.0.0.0:4001")    // Binary TCP
    .http("0.0.0.0:5001")   // HTTP + ordinary routes
    .run().await.unwrap();
}

Or merge WS into HTTP (same port):

#![allow(unused)]
fn main() {
AFast::new()
    .state(app_state)
    .service(svc)
    .ws("0.0.0.0:5001")
    .http("0.0.0.0:5001")   // Same port → auto-merged
    .run().await.unwrap();
}
Copied to clipboard!