Spikard — Part of the spikard polyglot web toolkit.
Rust-centric polyglot HTTP framework with OpenAPI/AsyncAPI/GraphQL/JSON-RPC codegen, tower-http middleware, and fixture-driven cross-language testing. Ruby bindings via Magnus with idiomatic Ruby API.
Install · Quick example · Features · Docs
What this package provides
-
Magnus-backed native extension — Ruby 3.2+ with native performance for routing and validation
-
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 hooks —
onRequest,preValidation,preHandler,onResponse,onError
Installation
gem:
gem install spikard
Bundler:
gem 'spikard'
System Requirements
- Ruby 3.2+ required
Quick example
require "spikard"
app = Spikard::App.new
app.get("/users/:id") do |params, _query, _body|
{ id: params[:id].to_i, name: "Alice" }
end
app.post("/users") do |_params, _query, body|
user = body
{ id: user["id"], name: user["name"] }
end
app.run(config: { port: 8000 })
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 |
Routing
require "spikard"
app = Spikard::App.new
app.get("/health") { |_params, _query, _body| { status: "ok" } }
app.post("/users") { |_params, _query, body| body }
Validation
require "spikard"
PaymentSchema = Dry::Schema.Params do
required(:id).filled(:string)
required(:amount).filled(:float)
end
app = Spikard::App.new
app.post("/payments") do |_params, _query, body|
PaymentSchema.call(body)
end
Middleware & configuration
require "spikard"
app = Spikard::App.new
app.on_request do |request|
puts "#{request[:method]} #{request[:path]}"
request
end
Resources
- Repository — source code, examples, and issues
- Examples — working implementations in all supported languages
- Contributing — how to contribute
License
MIT License — see LICENSE for details.