spikard 0.16.1

High-performance HTTP framework built on Axum and Tower-HTTP with type-safe routing, validation, WebSocket/SSE support, and lifecycle hooks
Documentation

Spikard — Part of the spikard polyglot web toolkit.

Rust-centric polyglot HTTP framework built on Axum and Tower-HTTP. Type-safe routing, JSON Schema validation, OpenAPI/AsyncAPI/GraphQL/JSON-RPC codegen, WebSocket/SSE, lifecycle hooks, and a tower-http middleware stack.

Install · Quick example · Features · Docs


What this package provides

  • Canonical Rust implementation — the core HTTP server used by all other bindings

  • Type-safe routing — HTTP definitions with path, query, body, and header validation across all bindings

  • Spec-driven codegen — OpenAPI 3.0, AsyncAPI 3.0, GraphQL SDL, and JSON-RPC 2.0 support

  • Cross-language parity — same DTOs, fixtures, and error model prevent runtime drift

  • Tower middleware — compression, rate limiting, timeouts, auth (JWT/API key), static files

  • Lifecycle hooksonRequest, preValidation, preHandler, onResponse, onError

Installation

cargo add spikard

System Requirements

Quick example

use axum::response::Json;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use spikard::{get, post, App, RequestContext};

#[derive(Serialize, Deserialize, JsonSchema)]
struct User {
    id: i64,
    name: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut app = App::new();

    app.route(get("/users/:id"), |ctx: RequestContext| async move {
        let id = ctx.path_param("id").unwrap_or("0").parse::<i64>().unwrap_or_default();
        Ok(Json(User { id, name: "Alice".into() }).into())
    })?;

    app.route(
        post("/users").request_body::<User>().response_body::<User>(),
        |ctx: RequestContext| async move {
            let user: User = ctx.json()?;
            Ok(Json(user).into())
        },
    )?;

    app.run().await?;
    Ok(())
}

Features

Feature Support
Type-safe routing Path, query, body, and header parameter validation
Request extraction Typed structs for JSON, form data, multipart, and raw bodies
Spec support OpenAPI 3.0 · AsyncAPI 3.0 · GraphQL SDL · JSON-RPC 2.0
Middleware Compression, rate limiting, timeouts, authentication, static files
Lifecycle hooks Request, pre-validation, pre-handler, response, and error hooks
WebSocket & SSE Bidirectional streams and server-sent events
Error handling Consistent error responses across all bindings via ProblemDetails
Fixture testing Shared JSON fixtures for behavioral consistency across languages
use spikard::prelude::*;

let mut app = App::new();

app.route(get("/health"), |_ctx: Context| async { Ok(Json(json!({"status": "ok"}))) })?;
app.route(post("/users"), |ctx: Context| async move {
    let user: serde_json::Value = ctx.json()?;
    Ok(Json(user))
})?;
use schemars::JsonSchema;
use serde::Deserialize;

#[derive(Deserialize, JsonSchema)]
struct Payment {
    id: String,
    amount: f64,
}

app.route(
    post("/payments").request_body::<Payment>().response_body::<Payment>(),
    |ctx: Context| async move {
        let payment: Payment = ctx.json()?;
        Ok(Json(payment))
    },
)?;
use tower_http::trace::TraceLayer;

let mut app = App::new();
app.layer(TraceLayer::new_for_http());

Resources

License

MIT License — see LICENSE for details.