acton-service
Production-ready Rust backend framework that scales from monolith to microservices
Build production backends with enforced best practices, dual HTTP+gRPC support, and comprehensive observability out of the box.
📚 Full Documentation | Quick Start | Examples
What is this?
Building production backends requires solving the same problems repeatedly: API versioning, health checks, observability, resilience patterns, authentication, connection pooling, and configuration management. Most frameworks leave these as optional concerns or implementation details.
acton-service provides a batteries-included, type-enforced framework where production best practices are the default path:
- Type-enforced API versioning - Impossible to bypass, compiler-enforced versioning
- Dual HTTP + gRPC - Run both protocols on the same port with automatic detection
- GraphQL transport - Versioned schemas that inherit the same middleware stack
- Complete authentication stack - PASETO (default) and JWT tokens, Argon2 password hashing, API keys, key rotation, OAuth/OIDC, sessions
- Cedar policy-based authorization - AWS Cedar integration for fine-grained access control
- Security & compliance built-in - BLAKE3 hash-chained audit logging, login lockout, NIST AC-2 account lifecycle, FIPS 140-3 capable crypto
- Production observability - OpenTelemetry tracing, metrics, and structured logging built-in
- Resilience patterns - Circuit breaker, retry logic, and bulkhead patterns included
- Multi-database support - PostgreSQL, Turso/libsql, SurrealDB, plus ClickHouse for analytics
- Zero-config defaults - XDG-compliant configuration with sensible production defaults and custom config extensions
- Kubernetes-ready - Automatic health/readiness probes for orchestration
It's opinionated, comprehensive, and designed for teams where best practices can't be optional.
Current Status: acton-service is under active development but broadly feature-complete. Transports (HTTP/gRPC/GraphQL/WebSocket/SSE), versioning, health checks, observability, resilience, the authentication and authorization stack, sessions, audit logging, and multi-database support all ship today. See the roadmap for what's next.
🚀 New to acton-service? Start with the 5-Minute Quickstart or follow the Complete Tutorial to build your first service.
Quick Start
use *;
async
# Versioned API endpoints
# Automatic health checks (Kubernetes-ready)
# OpenTelemetry metrics automatically collected
# Structured logs in JSON format automatically emitted
# Request IDs automatically generated and tracked
The type system enforces best practices:
// ❌ This won't compile - unversioned routes rejected at compile time
let app = new.route;
new.with_routes.build;
// ^^^ expected VersionedRoutes, found Router
Installation
Add to your Cargo.toml:
[]
= "0.27"
= { = "1", = ["full"] }
The default features (http, observability, crypto-aws-lc-rs) give you a versioned HTTP service with tracing, metrics, and health checks. Enable more as you need them — see Feature Flags.
Or use the CLI to scaffold a complete service:
&&
Why acton-service?
The Problem
Building production backends requires solving the same problems over and over:
- Dual Protocols: Modern deployments need both HTTP REST APIs and gRPC, but most frameworks make you choose one or run two separate servers
- Observability: Distributed tracing, metrics collection, and structured logging should be standard, not afterthoughts assembled from scattered libraries
- Authentication: Token validation, password hashing, key rotation, OAuth flows, and session management are security-critical and easy to get wrong
- Resilience Patterns: Circuit breakers, retries, and bulkheads are critical for production but tedious to implement correctly
- Health Checks: Every orchestrator needs them, but every team implements them differently with varying quality
- API Evolution: Breaking changes slip through because versioning is optional and easily forgotten
- Configuration: Production deployments need environment-based config without requiring boilerplate for every service
The Solution
acton-service provides a comprehensive, opinionated framework where production concerns are handled by default:
- Dual HTTP + gRPC - Run both protocols on the same port with automatic protocol detection, or use separate ports ✅
- Complete observability stack - OpenTelemetry tracing, HTTP metrics, and structured JSON logging configured out of the box ✅
- Production resilience patterns - Circuit breaker, exponential backoff retry, and bulkhead middleware included ✅
- Automatic health endpoints - Kubernetes-ready liveness and readiness probes with dependency monitoring ✅
- Type-enforced API versioning - The compiler prevents unversioned APIs; impossible to bypass ✅
- Zero-config defaults - XDG-compliant configuration with sensible defaults, environment variable overrides, and custom config extensions ✅
- Config-driven security - PASETO/JWT authentication, Cedar policy authorization, rate limiting, sessions, and audit logging wired automatically from configuration ✅
- Full identity stack - Password hashing (Argon2), API keys, signing-key rotation, OAuth/OIDC providers, login lockout, and account lifecycle management ✅
- Connection pool management - PostgreSQL, Turso, SurrealDB, ClickHouse, Redis, and NATS support with automatic retry and health checks ✅
Most importantly: it's designed for teams. The type system enforces best practices that individual contributors can't accidentally bypass.
Core Features
acton-service provides a comprehensive set of production-ready features that work together seamlessly:
Type-Safe API Versioning
The framework enforces API versioning at compile time through the type system:
// Define your API versions
let routes = new
.with_base_path
.add_version_deprecated
.add_version
.build_routes;
Deprecated versions automatically include Deprecation, Sunset, and Link headers per RFC 8594.
Automatic Health Checks
Health and readiness endpoints are included automatically and follow Kubernetes best practices:
// Health checks are automatic - no code needed
new
.with_routes
.build
.serve
.await?;
// Endpoints available immediately:
// GET /health - Liveness probe (process alive?)
// GET /ready - Readiness probe (dependencies healthy?)
The readiness endpoint automatically checks configured dependencies:
# config.toml
[]
= "postgres://localhost/mydb"
= false # Readiness fails if DB is down
[]
= "redis://localhost"
= true # Readiness succeeds even if Redis is down
Config-Driven Middleware
Production middleware is applied automatically from configuration — no manual layering required. Configure token authentication, rate limiting, sessions, and audit logging in config.toml, and ServiceBuilder wires the layers in the correct order:
# config.toml — PASETO v4 token authentication (the default token format)
[]
= "paseto"
= "v4"
= "public" # "local" (symmetric) or "public" (asymmetric)
= "./keys/paseto.key"
= "my-service"
# public_paths = ["/public/"] # Skip token auth for these prefixes
# Or JWT instead (requires the `jwt` feature):
# [token]
# format = "jwt"
# public_key_path = "./keys/jwt-public.pem"
# algorithm = "RS256" # RS256, ES256, HS256
# issuer = "https://auth.mydomain.com"
[]
= true
Validated claims are placed in request extensions, available to handlers, Cedar policies, GraphQL resolvers, and gRPC interceptors alike. Because everything is standard Tower middleware, you can still .layer() any custom or third-party middleware on your routers.
Available middleware (all HTTP and gRPC compatible):
Authentication & Authorization
- PASETO Authentication (default) - v4 local (symmetric) and public (asymmetric) token validation
- JWT Authentication (
jwtfeature) - RS256, ES256, HS256/384/512 algorithms - Cedar Policy-Based Authorization - AWS Cedar integration for fine-grained access control with:
- Declarative policy files for resource-based permissions
- Role-based and attribute-based access control (RBAC/ABAC)
- Manual policy reload endpoint (automatic hot-reload in progress)
- Optional Redis caching for sub-5ms policy decisions
- HTTP and gRPC support with customizable path normalization
- Claims structure with roles, permissions, user/client identification
- Redis-backed token revocation (optional)
Resilience & Reliability (resilience feature)
- Circuit Breaker - Configurable failure rate monitoring with auto-recovery
- Retry Logic - Exponential backoff with configurable max attempts
- Bulkhead - Concurrency limiting with wait timeouts to prevent overload
Rate Limiting
- Redis-backed rate limiting - Distributed rate limiting for multi-instance deployments
- Governor rate limiting (
governorfeature) - Local in-memory limiting with per-route configuration - Per-user and per-client limits via token claims
Observability
- Request Tracking - UUID-based request ID generation and propagation
- Distributed Tracing Headers - x-request-id, x-trace-id, x-span-id, x-correlation-id
- OpenTelemetry Metrics (
otel-metricsfeature) - HTTP request count, duration histograms, active requests, sizes - Sensitive Header Masking - Automatic masking in logs (authorization, cookies, API keys)
- Security Headers - Sensible defaults applied automatically
Standard HTTP Middleware
- Compression - gzip, br, deflate, zstd content encoding
- CORS - Configurable cross-origin policies
- Timeouts - Configurable request timeouts
- Body Size Limits - Prevent oversized payloads
- Panic Recovery - Graceful handling of panics with error logging
Authentication & Identity
Beyond token validation, the auth feature family provides a complete identity stack:
- Password hashing (
auth) - Argon2id with secure defaults (guide) - Token generation (
auth) - Mint PASETO or JWT tokens with typed claims (guide) - API keys (
auth) - BLAKE3-hashed API key issuance and validation (guide) - Signing-key rotation (
auth) - Rotate token signing keys with a drain grace period for in-flight tokens - OAuth 2.0 / OIDC (
oauth) - Pluggable provider integration built onoauth2andopenidconnect(guide) - Sessions (
session-memory/session-redis) - Cookie sessions viatower-sessionswith in-memory or Redis stores (guide) - Login lockout (
login-lockout) - Progressive delays and account lockout on repeated failures (guide) - Account lifecycle (
accounts/account-handlers) - NIST AC-2 aligned account management with optional pre-built REST handlers
Enable auth-full to get the entire stack in one flag.
Security, Audit & Compliance
- Audit logging (
audit) - BLAKE3 hash-chained, tamper-evident audit trails for auth, account, and request events, with storage backends for PostgreSQL, Turso, SurrealDB, and ClickHouse (guide) - TLS termination (
tls) - rustls-based HTTPS with automatic crypto-provider installation - FIPS 140-3 path -
aws-lc-rsis the default crypto provider; see Choosing a Crypto Provider - systemd journald (
journald) - Native journal integration for structured logs on Linux hosts
HTTP + gRPC Support
Run HTTP and gRPC services together on a single port:
use GrpcServicesBuilder;
use *;
// HTTP handlers
let http_routes = new
.add_version
.build_routes;
// gRPC services with health checks and reflection
let grpc_routes = new
.with_health
.with_reflection
.add_file_descriptor_set
.add_service
.build;
// Serve both protocols on the same port (automatic protocol detection)
new
.with_routes
.with_grpc_services
.build
.serve
.await?;
Configure gRPC in config.toml:
[]
= true
= false # Default: single-port mode with automatic protocol detection
# port = 9090 # Only used when use_separate_port = true
GraphQL Transport
Enable the graphql feature to expose schemas alongside REST and gRPC. Each
schema is mounted at /{base}/v{n}/graphql under the same versioned router,
so it inherits the framework middleware stack (auth, tracing, rate limiting,
Cedar, CORS). GET on the same path serves GraphiQL.
use *;
use ;
use ;
;
let routes = new
.with_base_path
.add_version
.build_routes;
let schema = build.finish;
let graphql = new
.with_base_path
.add_version
.build;
new
.with_routes
.with_versioned_graphql
.build
.serve
.await?;
With the graphql-cedar feature enabled, resolvers can call into the same
Cedar instance used by HTTP/gRPC middleware:
use CedarResolverCheck;
async
Configure runtime knobs (depth, complexity, GraphiQL, introspection) under
[graphql] in config.toml:
[]
= true
= true
= true
# max_query_depth = 12
# max_query_complexity = 200
Scaffold a graphql-ready service with the CLI:
WebSocket, SSE & Server-Rendered Web Apps
The framework isn't limited to APIs:
- WebSocket (
websocketfeature) - Real-time bidirectional connections mounted under the versioned router (guide, chat-server example) - Server-Sent Events (
ssefeature) - Streaming updates over plain HTTP (guide) - HTMX integration (
htmxfeature) - Request/response header extractors viaaxum-htmx(guide) - Askama templates (
askamafeature) - Compile-time checked HTML templates (guide)
Enable htmx-full (htmx + askama + sse + in-memory sessions) and you have everything needed for a hypermedia-driven web app — see the task-manager example.
Data Layer
Choose exactly one primary database backend (enforced at compile time), and optionally add ClickHouse for analytics:
- PostgreSQL (
database) - SQLx with compile-time checked queries (guide) - Turso / libsql (
turso) - Edge-replicated SQLite (guide) - SurrealDB (
surrealdb) - Multi-model database - ClickHouse (
clickhouse) - Analytical database, composable with any primary backend (guide) - Redis (
cache) - Connection pooling via deadpool (guide) - NATS JetStream (
events) - Event streaming (guide)
On top of the raw pools, opt into higher-level abstractions:
- Repository traits (
repository) - Database-agnostic CRUD abstractions - Handler traits (
handlers) - Pre-built REST CRUD patterns on top of repositories - Pagination (
pagination-axum/pagination-sqlx/pagination-full) - Query-parameter extraction and SQL pagination helpers
All pools are managed by AppState with automatic connection retry and health-check integration:
async
Zero-Configuration Defaults
Configuration follows the XDG Base Directory Specification:
~/.config/acton-service/
├── my-service/
│ └── config.toml
├── auth-service/
│ └── config.toml
└── user-service/
└── config.toml
Services load configuration automatically with environment variable overrides:
# No config file needed for development
# Override specific values
ACTON_SERVICE_PORT=9090
# Production config location
Custom Config Extensions: Extend the framework configuration with your own application-specific fields that are automatically loaded from the same config.toml:
// Framework automatically loads both framework and custom config
new
.with_routes
.build
.serve
.await
See the Configuration Guide for details.
Feature Flags
Defaults: http, observability, crypto-aws-lc-rs. Enable only what you need:
[]
= { = "0.27", = ["grpc", "database", "cache"] }
Transports & protocols
| Feature | Description |
|---|---|
http |
Axum HTTP framework (default) |
grpc |
Tonic gRPC with reflection, health checks, and interceptors |
graphql |
async-graphql transport, versioned alongside HTTP/gRPC |
graphql-cedar |
Cedar authorization callable from GraphQL resolvers |
websocket |
WebSocket support |
sse |
Server-Sent Events |
tls |
rustls-based HTTPS |
openapi |
Swagger UI / RapiDoc / ReDoc documentation |
Data layer (database, turso, and surrealdb are mutually exclusive — pick one)
| Feature | Description |
|---|---|
database |
PostgreSQL via SQLx |
turso |
Turso / libsql |
surrealdb |
SurrealDB |
clickhouse |
ClickHouse analytics (composable with any primary backend) |
cache |
Redis connection pooling |
events |
NATS JetStream |
repository |
Database-agnostic CRUD repository traits |
handlers |
REST CRUD handler traits (implies repository) |
pagination, pagination-axum, pagination-sqlx, pagination-full |
Pagination helpers |
Authentication & security (PASETO validation is always available; these add more)
| Feature | Description |
|---|---|
jwt |
JWT validation middleware |
auth |
Argon2 password hashing, token generation, API keys, key rotation |
oauth |
OAuth 2.0 / OIDC providers (implies auth) |
auth-full |
Everything: auth + oauth + jwt + cache + database + lockout + accounts |
cedar-authz |
AWS Cedar policy-based authorization |
session, session-memory, session-redis |
Cookie sessions (tower-sessions) |
login-lockout |
Progressive delay and account lockout |
accounts, account-handlers |
NIST AC-2 account lifecycle (+ pre-built REST handlers) |
audit |
BLAKE3 hash-chained audit logging |
Web apps
| Feature | Description |
|---|---|
htmx |
HTMX request/response integration |
askama |
Askama template engine |
htmx-full |
htmx + askama + sse + session-memory |
Observability & resilience
| Feature | Description |
|---|---|
observability |
OpenTelemetry tracing + structured logging (default) |
otel-metrics |
HTTP metrics middleware (implies observability) |
journald |
Native systemd journal logging |
resilience |
Circuit breaker + bulkhead middleware |
governor |
Local in-memory rate limiting |
Crypto provider (exactly one required — see below)
| Feature | Description |
|---|---|
crypto-aws-lc-rs |
aws-lc-rs rustls provider (default, FIPS 140-3 capable) |
crypto-ring |
ring rustls provider (no C toolchain requirement) |
Or use full to enable everything (with PostgreSQL as the database backend):
[]
= { = "0.27", = ["full"] }
See the Feature Flags guide for a decision tree.
Choosing a Crypto Provider
acton-service uses rustls for all TLS, with aws-lc-rs as the default
crypto provider. aws-lc-rs is FIPS 140-3 capable (via its fips feature),
aligned with rustls 0.23+, tonic 0.14+, and sqlx 0.8+, and faster than ring
on server hardware.
To use ring instead — for example, in environments without a C toolchain
that aws-lc-rs requires at build time:
[]
= { = "0.27", = false, = [
"http",
"observability",
"crypto-ring",
] }
Exactly one of crypto-aws-lc-rs (default) or crypto-ring must be enabled;
the build fails with a compile_error! otherwise. The chosen provider is
installed automatically when the TLS listener starts. Binaries that drive
reqwest, sqlx, or tonic TLS clients without using the framework's TLS
listener should call acton_service::crypto::ensure_default_crypto_provider()
once from main.
Examples
Minimal HTTP Service
use *;
async
async
All Bundled Examples
| Example | Shows | Run with |
|---|---|---|
simple-api |
Versioned API, zero config | cargo run --example simple-api |
users-api |
Deprecation headers (RFC 8594) | cargo run --example users-api |
custom-config |
Custom configuration extensions | cargo run --example custom-config |
ping-pong |
Dual-protocol HTTP + gRPC | cargo run --example ping-pong --features grpc |
single-port |
Single-port protocol detection, reflection, gRPC health | cargo run --example single-port --features grpc |
event-driven |
Event-driven architecture with NATS | cargo run --example event-driven --features grpc |
cedar-authz |
Cedar policies (guide) | cargo run --example cedar-authz --features cedar-authz,cache |
database-api |
PostgreSQL CRUD with SQLx | cargo run --example database-api --features database |
chat-server |
WebSocket real-time chat | cargo run --example chat-server --features websocket |
task-manager |
HTMX + Askama + SSE + sessions web app | cargo run --example task-manager --features htmx-full |
graphql-basic |
Versioned GraphQL transport | cargo run --example graphql-basic --features graphql |
test-observability |
Tracing/logging setup | cargo run --example test-observability |
test-metrics |
OpenTelemetry HTTP metrics | cargo run --example test-metrics --features otel-metrics |
See the Examples documentation for walkthroughs.
CLI Tool
The acton CLI scaffolds production-ready services:
# Install the CLI
# Create a new service
# Full-featured service
# Add components to an existing service
# Generate deployment and config artifacts
# Validate and iterate
See the CLI documentation for details.
Architecture
acton-service is built on production-proven Rust libraries:
- HTTP: axum - Ergonomic web framework
- gRPC: tonic - Native Rust gRPC
- GraphQL: async-graphql - GraphQL server library
- Database: SQLx (PostgreSQL), libsql (Turso), SurrealDB, clickhouse-rs
- Cache: redis-rs - Redis client
- Events: async-nats - NATS client
- Tokens: rusty_paseto - PASETO implementation
- Observability: OpenTelemetry - Distributed tracing
- Concurrency: acton-reactive - Actor-based background workers
Design principles:
- Type safety over runtime checks - Use the compiler to prevent mistakes
- Opinionated defaults - Best practices should be the default path
- Explicit over implicit - No magic, clear code flow
- Production-ready by default - Health checks, config, observability included
- Modular features - Only compile what you need
Documentation
📚 Full Documentation Site - Complete guides, API reference, and examples
Getting Started
- Quickstart - Get a service running in 5 minutes
- Tutorial - Complete step-by-step guide to building a production service
- Installation - Setup and feature selection
- Feature Flags - Decision tree for choosing the right features
- Comparison - How acton-service compares to Axum, Actix-Web, and others
Guides
- Configuration - Environment and file-based configuration
- API Versioning - Type-safe versioning patterns
- Health Checks - Kubernetes liveness and readiness
- Database - PostgreSQL, Turso, and ClickHouse
- Token Authentication - PASETO and JWT validation
- OAuth / OIDC - Provider integration
- Sessions - Cookie sessions with memory or Redis stores
- Cedar Authorization - Policy-based access control
- Audit Logging - Tamper-evident audit trails
- Rate Limiting - Distributed and local strategies
- Resilience - Circuit breaker, retry, bulkhead
- GraphQL - Versioned GraphQL transport
- WebSocket - Real-time connections
- HTMX - Hypermedia-driven web apps
- Crypto Provider - aws-lc-rs vs ring, FIPS
- Observability - Metrics, tracing, and logging
- Production Deployment - Production best practices
Reference
- Examples - Complete working examples
- Troubleshooting - Common issues and solutions
- FAQ - Frequently asked questions
- Glossary - Technical term definitions
- API Documentation:
cargo doc --open
Performance
acton-service is built on tokio and axum, which are known for excellent performance characteristics. The framework adds minimal abstraction overhead beyond the underlying libraries.
Performance benchmarks will be published as the project matures. Performance is primarily determined by your application logic and the underlying libraries (axum for HTTP, tonic for gRPC, sqlx for database operations).
Deployment
Docker
FROM rust:1.84-slim as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/my-service /usr/local/bin/
EXPOSE 8080
CMD ["my-service"]
Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-service
spec:
replicas: 3
selector:
matchLabels:
app: my-service
template:
metadata:
labels:
app: my-service
spec:
containers:
- name: my-service
image: my-service:latest
ports:
- containerPort: 8080
env:
- name: ACTON_SERVICE_PORT
value: "8080"
- name: ACTON_DATABASE_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: url
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
Generate complete Kubernetes manifests with the CLI:
Migration Guide
From Axum
acton-service is a thin layer over axum. Your existing handlers work unchanged:
// Your existing axum handler
async
// Works directly in acton-service
let routes = new
.add_version
.build_routes;
Main changes:
- Routes must be versioned (wrap in
VersionedApiBuilder) - Use
ServiceBuilderinstead ofaxum::serve() - Configuration loaded automatically (optional)
From Actix-Web
Similar handler patterns, different framework:
// Actix-web
async
// acton-service
async
See the Examples documentation for complete migration examples.
Roadmap
Implemented ✅
- Dual Protocol Support: Single-port HTTP + gRPC multiplexing with automatic protocol detection
- GraphQL Transport: async-graphql integration with path-versioned schemas, GraphiQL, claims propagation, and Cedar resolver authorization
- WebSocket & SSE: Real-time connections and server-sent events under the versioned router
- Complete Observability Stack: OpenTelemetry tracing/metrics (OTLP exporter), structured JSON logging, journald integration, distributed request tracing
- Production Resilience Patterns: Circuit breaker, exponential backoff retry, bulkhead (concurrency limiting)
- Token Authentication: PASETO v4 (default) and JWT (RS256/ES256/HS256/384/512), config-driven and auto-applied, with Redis-backed revocation
- Identity Stack: Argon2 password hashing, API keys, token generation, signing-key rotation, OAuth 2.0/OIDC providers, cookie sessions (memory/Redis)
- Security & Compliance: BLAKE3 hash-chained audit logging with pluggable storage, login lockout, NIST AC-2 account lifecycle, TLS with FIPS 140-3 capable crypto provider
- Cedar Policy-Based Authorization: AWS Cedar integration with declarative policies, manual reload endpoint, Redis caching, HTTP/gRPC/GraphQL support, customizable path normalization
- Type-Enforced API Versioning: Compile-time enforcement with RFC 8594 deprecation headers
- Automatic Health Checks: Kubernetes-ready liveness/readiness probes with dependency monitoring (database, cache, events)
- Multi-Database Support: PostgreSQL (SQLx), Turso/libsql, SurrealDB, ClickHouse analytics, Redis (Deadpool), NATS JetStream — all with automatic retry and health checks
- Persistence Abstractions: Repository and REST handler traits, pagination helpers
- Web App Stack: HTMX integration, Askama templates, session-backed hypermedia apps
- XDG-Compliant Configuration: Multi-source config with environment variable overrides and sensible defaults
- OpenAPI/Swagger Support: Multiple UI options (Swagger UI, RapiDoc, ReDoc) with multi-version documentation
- CLI Tooling: Service scaffolding plus
add endpoint/worker/grpc/graphql/middleware/version,generate config/deployment/proto,validate, anddevcommands - gRPC Features: Reflection service, health checks, interceptors, middleware parity with HTTP
In Progress 🚧
- Cedar automatic policy hot-reload (manual reload endpoint available today)
- Additional OpenAPI schema generation utilities
Planned 📋
- GraphQL subscriptions over WebSocket
- Service mesh integration (Istio, Linkerd)
- Additional database backends (MySQL, MongoDB)
- Observability dashboards and sample configurations
- Enhanced metrics (custom business metrics, SLO tracking)
- Advanced rate limiting strategies (sliding log, token bucket refinements)
FAQ
Q: How does this compare to using Axum or Tonic directly?
A: acton-service is built on top of Axum (HTTP) and Tonic (gRPC) but adds production-ready features as defaults: type-enforced versioning, automatic health checks, observability stack, resilience patterns, a complete auth stack, and connection pool management. If you need maximum flexibility, use the underlying libraries directly. If you want production best practices enforced by the type system, use acton-service.
Q: Can I run both HTTP and gRPC on the same port?
A: Yes! This is a core feature. acton-service provides automatic protocol detection allowing HTTP and gRPC to share a single port, or you can configure separate ports if preferred.
Q: Does this work with existing axum middleware?
A: Yes. All Tower middleware works unchanged. Use .layer() with any tower middleware. The framework's own middleware (token auth, Cedar, rate limiting, audit, sessions) is applied automatically from configuration in the correct order.
Q: Why PASETO instead of JWT by default?
A: PASETO (Platform-Agnostic Security Tokens) eliminates JWT's algorithm-confusion pitfalls by fixing the algorithm per version. JWT remains fully supported behind the jwt feature — configure whichever your infrastructure requires under [token].
Q: Why enforce versioning so strictly?
A: API versioning is critical in production but easy to skip when deadlines loom. Making it impossible to bypass via the type system ensures consistent team practices and prevents breaking changes from slipping through.
Q: Can I use this without the enforced versioning?
A: No. If you need unversioned routes, use axum directly. acton-service is opinionated about API evolution and production best practices.
Q: Is this production-ready?
A: Yes, with the usual caveats of a pre-1.0 crate: expect occasional breaking changes between minor versions (documented in the CHANGELOG). The framework is built on battle-tested libraries (axum, tonic, sqlx) and its features — transports, auth, authorization, audit, resilience, pooling — ship complete with tests. Review the roadmap and test thoroughly for your use case.
Q: What's the performance overhead?
A: Minimal. The framework is a thin abstraction layer over high-performance libraries (tokio, axum, tonic). The type-enforced patterns are compile-time checks with zero runtime cost. Middleware like circuit breakers and metrics add small overhead for production safety benefits.
Contributing
Contributions are welcome! Areas of focus:
- Additional middleware patterns
- More comprehensive examples
- Documentation improvements
- Performance optimizations
- CLI enhancements
See CONTRIBUTING.md for guidelines (coming soon).
Changelog
See CHANGELOG.md for version history.
License
Licensed under the MIT License. See LICENSE for details.
Credits
Built with excellent open source libraries:
- tokio - Async runtime
- axum - Web framework
- tonic - gRPC implementation
- tower - Middleware foundation
- SQLx - Database client
- rusty_paseto - PASETO tokens
Inspired by production challenges at scale. Built by developers who've maintained backend services in production.
Sponsor
Govcraft is a one-person shop—no corporate backing, no investors, just me building useful tools. If this project helps you, sponsoring keeps the work going.