Architecture
This document describes Barbacane’s system architecture for contributors.
High-Level Overview
┌─────────────────────────────────────────────────────────────────┐
│ Control Plane │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ OpenAPI │───▶│ Parser │───▶│ Compiler │ │
│ │ Specs │ │ │ │ (validation, trie) │ │
│ └─────────────┘ └─────────────┘ └──────────┬──────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ .bca Artifact │ │
│ └───────┬───────┘ │
└───────────────────────────────────────────────────┼─────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Data Plane │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Artifact │───▶│ Router │───▶│ Dispatchers │ │
│ │ Loader │ │ (trie) │ │ (mock, http, ...) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ │ │ │ │
│ │ ▼ ▼ │
│ │ ┌─────────────┐ ┌─────────────────────┐ │
│ │ │ Middlewares │◀──▶│ Plugin Runtime │ │
│ │ │ Chain │ │ (WASM) │ │
│ │ └─────────────┘ └─────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ HTTP Server (hyper) │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Crate Structure
The project is organized as a Cargo workspace with specialized crates:
crates/
├── barbacane/ # Main CLI (compile, validate, serve)
├── barbacane-control/ # Control plane CLI (spec upload, plugin register)
├── barbacane-compiler/ # Spec compilation & artifact format
├── barbacane-spec-parser/ # OpenAPI/AsyncAPI parsing
├── barbacane-router/ # Prefix trie request routing
├── barbacane-validator/ # Request validation
├── barbacane-wasm/ # WASM plugin runtime (wasmtime)
├── barbacane-plugin-sdk/ # WASM plugin development kit
├── barbacane-plugin-macros/# Proc macros for plugin development
└── barbacane-test/ # Integration test harness
Crate Dependencies
barbacane (CLI / data plane)
├── barbacane-compiler
│ ├── barbacane-spec-parser
│ └── barbacane-router
├── barbacane-validator
├── barbacane-router
└── barbacane-wasm
└── barbacane-plugin-sdk
barbacane-plugin-sdk
└── barbacane-plugin-macros
barbacane-test
└── barbacane-compiler
Crate Details
barbacane-spec-parser
Parses OpenAPI and AsyncAPI specifications and extracts Barbacane extensions.
Key types:
ApiSpec- Parsed specification with operations and metadataOperation- Single API operation with dispatch/middleware configDispatchConfig- Dispatcher name and configurationMiddlewareConfig- Middleware name and configurationChannel- AsyncAPI channel with publish/subscribe operations
Supported formats:
- OpenAPI 3.0.x
- OpenAPI 3.1.x
- OpenAPI 3.2.x (draft)
- AsyncAPI 3.x (parsing supported, dispatchers planned)
barbacane-router
Prefix trie implementation for fast HTTP request routing.
Key types:
Router- The routing trieRouteEntry- Points to compiled operation indexRouteMatch- Found / MethodNotAllowed / NotFound
Features:
- O(path length) lookup
- Static routes take precedence over parameters
- Path parameter extraction
- Path normalization (trailing slashes, double slashes)
barbacane-compiler
Compiles parsed specs into deployable artifacts.
Responsibilities:
- Validate dispatcher requirements (every operation needs dispatch)
- Detect routing conflicts (same path+method in multiple specs)
- Build routing trie
- Package into
.bcaarchive
Artifact format (.bca):
artifact.bca (tar.gz)
├── manifest.json # Metadata, checksums, bundled plugins
├── routes.json # Compiled operations
├── specs/ # Embedded source specs
│ ├── api.yaml
│ └── ...
└── plugins/ # Bundled WASM plugins (optional)
├── rate-limit.wasm
└── ...
barbacane
Main CLI with three subcommands:
compile- Compile specs to artifactvalidate- Validate specs without compilationserve- Run the gateway
barbacane (serve)
Data plane binary - the actual gateway.
Startup flow:
- Load artifact from disk
- Load compiled routes from artifact
- Load bundled plugins from artifact
- Compile WASM modules (AOT)
- Resolve secrets - scan configs for
env://andfile://references - Create plugin instance pool with resolved secrets
- Start HTTP server
If any secret cannot be resolved in step 5, the gateway exits with code 13.
Request flow:
- Receive HTTP request
- Check reserved endpoints (
/__barbacane/*) - Route lookup in trie
- Apply middleware chain
- Dispatch to handler
- Apply response middlewares
- Send response
barbacane-wasm
WASM plugin runtime built on wasmtime.
Key types:
WasmEngine- Configured wasmtime engine with AOT compilationInstancePool- Instance pooling per (plugin_name, config_hash)PluginInstance- Single WASM instance with host function bindingsMiddlewareChain- Ordered middleware execution
Host functions:
host_set_output- Plugin writes result to host bufferhost_log- Structured logging with trace contexthost_context_get/set- Per-request key-value storehost_clock_now- Monotonic time in millisecondshost_http_call- Make outbound HTTP requestshost_http_read_result- Read HTTP response datahost_get_secret- Get a resolved secret by referencehost_secret_read_result- Read secret value into plugin memory
Resource limits:
- 16 MB linear memory
- 1 MB stack
- 100ms execution timeout (via fuel)
barbacane-plugin-sdk
SDK for developing WASM plugins (dispatchers and middlewares).
Provides:
Request,Response,Actiontypes#[barbacane_middleware]macro - generates WASM exports for middlewares#[barbacane_dispatcher]macro - generates WASM exports for dispatchers- Host function FFI bindings
barbacane-plugin-macros
Proc macros for plugin development (used by barbacane-plugin-sdk).
Generates:
init(ptr, len) -> i32- Initialize with JSON configon_request(ptr, len) -> i32- Process request (0=continue, 1=short-circuit)on_response(ptr, len) -> i32- Process responsedispatch(ptr, len) -> i32- Handle request and return response
barbacane-test
Integration testing harness.
Key types:
TestGateway- Spins up gateway with compiled artifact on random port- Request helpers for easy HTTP testing
Request Lifecycle
┌──────────────────────────────────────────────────────────────────┐
│ Request Flow │
└──────────────────────────────────────────────────────────────────┘
Client Request
│
▼
┌───────────┐
│ Receive │ TCP accept, HTTP parse
└─────┬─────┘
│
▼
┌───────────┐
│ Reserved │ /__barbacane/* check
│ Endpoint │ (health, openapi, etc.)
└─────┬─────┘
│ Not reserved
▼
┌───────────┐
│ Route │ Trie lookup: path + method
│ Lookup │ Returns: Found / NotFound / MethodNotAllowed
└─────┬─────┘
│ Found
▼
┌───────────┐
│ Middleware│ Global middlewares
│ (Global) │ auth, rate-limit, cors, etc.
└─────┬─────┘
│
▼
┌───────────┐
│ Middleware│ Operation-specific middlewares
│ (Operation│ May override global config
└─────┬─────┘
│
▼
┌───────────┐
│ Dispatch │ mock, http, custom plugins
└─────┬─────┘
│
▼
┌───────────┐
│ Response │ Reverse middleware chain
│ Middleware│ Transform response
└─────┬─────┘
│
▼
┌───────────┐
│ Send │ HTTP response to client
└───────────┘
Plugin Architecture
Plugins are WebAssembly (WASM) modules that implement dispatchers or middlewares.
┌─────────────────────────────────────────────────────────┐
│ Plugin Contract │
├─────────────────────────────────────────────────────────┤
│ Middleware exports: │
│ - on_request(ctx) -> Continue | Respond | Error │
│ - on_response(ctx) -> Continue | Modify | Error │
│ │
│ Dispatcher exports: │
│ - dispatch(ctx) -> Response | Error │
│ │
│ Common: │
│ - init(config) -> Ok | Error │
├─────────────────────────────────────────────────────────┤
│ Host functions (provided by runtime): │
│ - http_call(req) -> Response │
│ - log(level, message) │
│ - get_secret(name) -> Value │
│ - context_get(key) -> Value │
│ - context_set(key, value) │
└─────────────────────────────────────────────────────────┘
Key Design Decisions
Compilation Model
Decision: Compile specs to artifacts at build time, not runtime.
Rationale:
- Fail fast: catch configuration errors before deployment
- Reproducible: artifact is immutable, version-controlled
- Fast startup: no parsing at runtime
- Secure: no spec files needed in production
Prefix Trie Routing
Decision: Use a prefix trie for routing instead of linear search.
Rationale:
- O(path length) lookup regardless of route count
- Natural handling of path parameters
- Easy static-over-param precedence
WASM Plugins
Decision: Use WebAssembly for plugin sandboxing.
Rationale:
- Language agnostic (Rust, Go, AssemblyScript, etc.)
- Secure sandbox (no filesystem, network without host functions)
- Near-native performance
- Portable across platforms
Embedded Specs
Decision: Embed source specs in the artifact.
Rationale:
- Self-documenting:
/__barbacane/openapialways works - No external dependencies at runtime
- Version consistency
Testing Strategy
Unit Tests (per crate)
├── Parser: various OpenAPI versions, edge cases
├── Router: routing scenarios, parameters, precedence
└── Compiler: validation, conflict detection
Integration Tests (barbacane-test)
└── TestGateway: full request/response cycles
├── Health endpoint
├── Mock dispatcher
├── 404 / 405 handling
└── Path parameters
Run all tests:
cargo test --workspace
Performance Considerations
- Zero-copy routing: Trie lookup doesn’t allocate
- Connection reuse: HTTP/1.1 keep-alive by default
- Async I/O: Tokio runtime, non-blocking everything
- Plugin caching: WASM modules compiled once, instantiated per-request
Future Directions
- gRPC passthrough: Transparent proxying for gRPC services
- Hot reload: Reload artifacts without restart via control plane notifications
- Cluster mode: Distributed configuration across multiple nodes
- AsyncAPI dispatchers: Event-driven APIs with Kafka/NATS dispatch (parsing already supported)