Architecture¶
Spikard splits concerns between a Rust core and language-specific bindings so teams can mix runtimes without re-implementing the platform.
Layers¶
- Rust core (
crates/spikard) – routing, middleware, request parsing, streaming, and error handling. - Binding crates (
crates/spikard-py,crates/spikard-node,crates/spikard-rb,crates/spikard-php) – expose idiomatic APIs per language while delegating execution to the Rust runtime. - CLI (
crates/spikard-cli) – entrypoint that boots the HTTP server, loads binding code, and orchestrates code generation. - Codegen (
crates/spikard-codegen,tools/test-generator) – generates DTOs/handlers and fixture-driven tests from OpenAPI/AsyncAPI contracts.
Design Principles¶
- One runtime, many languages – identical semantics for routing, validation, middleware, and streaming regardless of binding.
- Contract-first – JSON Schema and generated DTOs keep request/response shapes consistent across bindings.
- Performance with safety – Tokio/Axum base, zero-copy where possible, and strict validation before handler invocation.
- Extensibility – middleware hooks and plugin points allow cross-cutting behavior without forked frameworks.
Data Flow¶
- Inbound request hits the Rust HTTP server.
- Routing and middleware run in Rust, enriching context, enforcing auth, logging, and tracing.
- Binding bridge converts the request into the language-native representation (Python
App, TypeScriptApp, RubyApp, RustApp). - Handler execution returns a typed value that is converted back into a canonical response (JSON, streaming body, etc.).
- Validation checks schemas on both ingress and egress when configured.
See ADR 0001 for the original rationale and Python Binding Architecture for a deep dive into the PyO3 path.
High-level flow¶
graph TD
subgraph Client
A[Client]
end
subgraph RustCore[Rust Core]
B[Axum Router]
C[Middleware Stack]
D[Validation]
E[Binding Bridge]
end
subgraph PythonBinding[Python Binding]
F[PyO3
+ msgspec]
end
subgraph NodeBinding[TypeScript Binding]
G[NAPI-RS
+ Zod]
end
subgraph RubyBinding[Ruby Binding]
H[Magnus
+ dry-schema]
end
subgraph RustNative[Rust API]
I[Handlers]
end
A --> B --> C --> D --> E
E --> F
E --> G
E --> H
E --> I