Releases: Tuntii/RustAPI
v0.1.537 - Builder split (#201) & maintainability
Changed
- Maintainability (#201): Split
app/builder.rsinto internalrouting,openapi,health, andrunmodules. Everyrustapi-core/src/**/*.rsfile is now under the 50KB limit. - Run lifecycle: All
run*entrypoints consistently executeon_shutdownhooks after the server exits. - Test layout: Oversized router and extract test bodies moved to
tests/support/*_lib.rsviainclude!for--libcoverage.
Fixed
- Plain
run_http3/run_http3_dev/run_dual_stackno longer drop pendingon_shutdownhooks.
Install
rustapi-rs = "0.1.537"Full Changelog: v0.1.528...v0.1.537
v0.1.508 - MCP Permission Scoping & Fixes
MCP Framework-Native Permission Scoping (major improvement)
- Introduced McpOperation + x-mcp OpenAPI extension
- #[mcp(skip | write | readonly | require=...)] route attributes
- ToolPolicy (ReadOnly default, All, future Custom)
- Permission metadata in tools/list for agents
- More docs and examples
Full details in PR #198.
v0.1.507 - MCP In-Process, CLI & Lifetime Sponsors
[0.1.507] - 2026-06-19
Added
- MCP In-Process Invocation: InvocationMode::InProcess / Auto on McpConfig. When a McpServer is created via rom_rustapi, tool calls can execute directly through the Router + LayerStack + interceptors with no network hop. RustApi::request_dispatcher() and internal RequestInvoker / RequestDispatcher.
- Typical result: ~28 µs per call (in-process) vs ~1.3 ms (proxy via live localhost HTTP) for 1000 sequential calls — ~45-50× speedup.
- cargo rustapi mcp generate CLI: Turn any OpenAPI 3.x spec (FastAPI, Express, Go, etc.) into a running MCP server. Supports --spec, --url, --api, --target, tag/path filtering, and --stdio.
- MCP stdio transport: --stdio flag for desktop AI clients (Claude Desktop, etc.).
- Lifetime Sponsors: emirtom, erencanbas, arda-num added as LIFE-TIME personal sponsors with embedded GitHub profile avatars in Hall of Fame.
- New cookbook recipes: In-Process Invocation, OpenAPI→MCP CLI, and stdio transport. Updated main MCP recipe and README.
- Various polishes from code review (state preservation, stdio UX, error formatting, test flakiness handling).
Changed
- OpenAPI deserialization in
ustapi-openapi is now significantly more tolerant of real-world/partial specs (added #[serde(default)] on maps and optional fields) so the CLI works reliably with external APIs. - Router now derives Clone (aids in-process sharing patterns).
- McpConfig gained invocation_mode(...).
- Public API surface updated with RequestDispatcher.
Documentation
- Major updates to MCP coverage in README, cookbook, and plan documents.
- Sponsors section now includes permanent lifetime sponsors with profile embeds.
- Release notes aligned for v0.1.507.
v0.1.501
RustAPI v0.1.501
Native MCP support — Your API is now an AI agent toolkit.
🚀 Highlights
-
Full MCP (Model Context Protocol) support via the new
rustapi-mcpcrate- Automatically expose routes as tools using your existing OpenAPI spec
- Tag-based filtering (
allowed_tags) so agents only see what you want them to - Real proxied
tools/call— every call goes through your normal middleware, extractors, validation, and error handling - Works great with Claude, Cursor, custom agents, etc.
-
One-liner enablement
.use_mcp(McpConfig::new().allowed_tags(vec!["public", "agent"]))
-
Crate cleanup: Consolidated from 13 crates down to 9.
rustapi-testing,jobs,view, andtoonare now features instead of separate published crates. -
Better observability UX
- Dashboard now has route filters + integrated replay browser
- Improved replay admin API with pagination and filters
📦 New / Notable Crates & Features
rustapi-mcp(new)protocol-mcp/mcpfeature onrustapi-rs- New
mcp_toolsexample (HTTP server + MCP sidecar together) - Cookbook: "MCP Integration (Agent Tools)"
🔗 Links
- Full Changelog: v0.1.470...v0.1.501
- Documentation: https://docs.rs/rustapi-rs
- Cookbook MCP recipe: in the docs
Ready for agents. Turn your Rust backend into something LLMs can actually use safely and correctly.
cargo add rustapi-rs --features fullThen just add .use_mcp(...) and you're done.
v0.1.470
🎯 Highlights
v0.1.470 delivers the Embedded Isometric System Dashboard — an opt-in, self-contained control plane that lives inside your RustAPI process. No external observability stack required.
| Feature | Crate | Impact |
|---|---|---|
Embedded Dashboard (/__rustapi/dashboard) |
rustapi-core |
Visual control plane with execution-path counters, route topology, and health summary |
| Dashboard JSON API | rustapi-core |
7 bearer-protected endpoints: snapshot, routes, metrics, topology, events, health, replay |
| Route Inventory | rustapi-core |
Per-route hit counts, average latency, error rate, group/method/tag metadata |
| Replay Browser | rustapi-core + rustapi-extras |
UI-native replay list/detail/diff wired to ReplayLayer admin API |
| Execution-Path Telemetry | rustapi-core |
Atomic counters for Ultra Fast / Fast / Full paths with near-zero overhead |
DashboardConfig |
rustapi-core |
.admin_token(), .path(), .title(), .replay_api_path() builder |
| Public re-exports | rustapi-rs |
DashboardConfig, DashboardMetrics, DashboardSnapshot in prelude |
| Dashboard cookbook recipe | docs/cookbook |
Full walkthrough with SVG preview, feature flags, and security notice |
📊 Embedded Isometric System Dashboard
Enable the dashboard with a single builder call:
use rustapi_rs::prelude::*;
#[tokio::main]
async fn main() {
RustApi::new()
.route("/api/users", get(list_users))
.health_endpoints()
.dashboard(
DashboardConfig::new()
.admin_token("my-secret-token")
)
.run("127.0.0.1:8080")
.await;
}Open http://localhost:8080/__rustapi/dashboard in your browser and enter the admin token. The HTML shell loads without authentication; all JSON API endpoints require Authorization: Bearer <token> when admin_token is configured.
Dashboard JSON API
| Endpoint | Description |
|---|---|
GET /__rustapi/dashboard/api/snapshot |
Full telemetry snapshot |
GET /__rustapi/dashboard/api/routes |
Route inventory with method / tag / group metadata |
GET /__rustapi/dashboard/api/metrics |
Live atomic counters |
GET /__rustapi/dashboard/api/topology |
Route graph for topology visualizations |
GET /__rustapi/dashboard/api/events |
Request-stage counters (received / routed / completed / failed) |
GET /__rustapi/dashboard/api/health |
Health endpoint discovery summary |
GET /__rustapi/dashboard/api/replay |
Replay index wired to ReplayLayer admin API |
Execution-path telemetry
The dashboard tracks which server execution branch handled each request using lock-free atomics:
| Path | Condition |
|---|---|
| Ultra Fast | No middleware AND no interceptors |
| Fast | No middleware, has interceptors |
| Full | Has middleware layers |
Telemetry is compiled out when the core-dashboard feature is not enabled — no overhead at all for standard builds.
Replay browser
When extras-replay is also enabled, the dashboard surfaces a replay browser panel that pages through recorded traffic, shows request/response detail, and renders diffs. It reuses the existing ReplayLayer admin HTTP surface and adds UI-friendly offset, status_max, from, to, tag, and order query parameters.
⚙️ Feature flag
[dependencies]
# Dashboard only
rustapi-rs = { version = "0.1.470", features = ["core-dashboard"] }
# Dashboard + replay browser
rustapi-rs = { version = "0.1.470", features = ["core-dashboard", "extras-replay"] }The feature is opt-in. Nothing is exposed unless core-dashboard is enabled in your Cargo.toml.
🔒 Security
- The HTML page is served without bearer auth so browsers can load it — consistent with the browser's inability to set
Authorizationheaders on page navigations. - All JSON API endpoints enforce
Authorization: Bearer <token>whenadmin_tokenis configured. - The HTML response sets a strict
Content-Security-Policy:default-src 'none'with narrow allowances for inline scripts/styles andconnect-src 'self'only. Referrer-Policy: no-referrerandX-Content-Type-Options: nosniffare set on every dashboard response.- Dashboard routes are never exposed unless you call
.dashboard(...)explicitly on theRustApibuilder.
📦 Changed files
| File | Change |
|---|---|
crates/rustapi-core/src/dashboard/ |
New module: auth, config, metrics, routes, embedded HTML |
crates/rustapi-core/src/server.rs |
Dashboard dispatch wired into request pipeline |
crates/rustapi-core/src/app.rs |
.dashboard() builder method |
crates/rustapi-extras/src/replay/routes.rs |
Pagination/filter params for UI consumption |
crates/rustapi-rs/src/lib.rs |
Re-exports: DashboardConfig, DashboardMetrics, DashboardSnapshot |
api/public/rustapi-rs.all-features.txt |
Snapshot updated with new public types |
docs/cookbook/src/recipes/dashboard.md |
New recipe with SVG preview and security guidance |
v0.1.443
What's Changed
- Bump tonic from 0.14.3 to 0.14.5 by @dependabot[bot] in #151
- Bump redis from 0.24.0 to 1.0.4 by @dependabot[bot] in #146
- Bump anyhow from 1.0.101 to 1.0.102 by @dependabot[bot] in #150
- Bump syn from 2.0.114 to 2.0.117 by @dependabot[bot] in #149
- Bump actions/upload-artifact from 4 to 7 by @dependabot[bot] in #141
- Bump tempfile from 3.24.0 to 3.26.0 by @dependabot[bot] in #148
- Bump indicatif from 0.17.11 to 0.18.4 by @dependabot[bot] in #143
- Bump tonic-health from 0.14.3 to 0.14.5 by @dependabot[bot] in #142
- Bump clap from 4.5.57 to 4.5.60 by @dependabot[bot] in #144
- Bump tokio from 1.49.0 to 1.50.0 by @dependabot[bot] in #147
- Bump rustls from 0.23.36 to 0.23.37 by @dependabot[bot] in #145
Full Changelog: v0.1.412...v0.1.443
v0.1.412
Full Changelog: v0.1.410...v0.1.412
v0.1.410
RustAPI v0.1.410 Release Notes
Release Date: March 9, 2026
Full Changelog: v0.1.397...v0.1.410
Benchmark Source of Truth: Current benchmark methodology and canonical performance claims live in docs/PERFORMANCE_BENCHMARKS.md. Historical release-specific benchmark notes should be treated as point-in-time snapshots unless they are linked from that document.
🎯 Highlights
v0.1.410 is the Production Baseline release. It delivers everything you need to go from prototype to production-ready service with a single builder call — health probes, session management, rate limiting, observability tooling, and a suite of real-world examples.
| Feature | Crate | Impact |
|---|---|---|
| Production Defaults Preset | rustapi-core |
One-call production setup: health probes + tracing + request IDs |
| Health Check System | rustapi-core |
Built-in /health, /ready, /live with custom checks |
| Session Management | rustapi-extras |
Cookie-backed sessions with pluggable stores |
| Rate Limiting Strategies | rustapi-extras |
Fixed window, sliding window, and token bucket |
| CLI: bench & observability | cargo-rustapi |
New bench and observability subcommands |
| Multipart Streaming | rustapi-core |
Enhanced streaming multipart with progress tracking |
| 4 New Examples | rustapi-rs |
Auth, CRUD, Jobs, Streaming — ready to copy |
| 10+ Cookbook Recipes | docs/cookbook |
Migration guides, session auth, observability, error handling |
🏭 Production Defaults Preset
Go production-ready with a single call:
use rustapi_rs::prelude::*;
#[tokio::main]
async fn main() {
RustApi::new()
.production_defaults("my-service")
.run("0.0.0.0:3000")
.await;
}This enables:
RequestIdLayer— unique ID on every requestTracingLayer— structured logging with service metadata/health,/ready,/live— Kubernetes-compatible probes
Customizable via ProductionDefaultsConfig:
RustApi::new()
.production_defaults_with_config(
ProductionDefaultsConfig::new("my-service")
.version("1.2.3")
.tracing_level(tracing::Level::DEBUG)
.request_id(true)
.health_endpoints(true)
)
.run("0.0.0.0:3000")
.await;🏥 Health Check System
Full health check module with builder API, custom checks, and OpenAPI integration:
use rustapi_rs::prelude::*;
let health = HealthCheckBuilder::new(true)
.add_check("database", || async {
// Check database connectivity
HealthStatus::healthy()
})
.add_check("redis", || async {
HealthStatus::degraded("high latency".into())
})
.version("1.0.0")
.build();
RustApi::new()
.with_health_check(health)
.health_endpoints()
.run("0.0.0.0:3000")
.await;/health— aggregated status of all checks (200 or 503)/ready— dependency readiness (200 or 503)/live— lightweight liveness probe (always 200)- Configurable paths via
HealthEndpointConfig HealthStatusvariants:Healthy,Unhealthy { reason },Degraded { reason }
🔐 Session Management
Cookie-backed session management with pluggable storage backends:
use rustapi_rs::prelude::*;
use rustapi_rs::extras::session::*;
let store = MemorySessionStore::new();
RustApi::new()
.layer(SessionLayer::new(
store,
SessionConfig::default()
.cookie_name("my_session")
.ttl(Duration::from_secs(3600))
.secure(true)
.http_only(true)
.same_site(SameSite::Lax)
))
.run("0.0.0.0:3000")
.await;Handler-side usage:
#[post("/login")]
async fn login(session: Session, body: Json<LoginRequest>) -> Result<Json<Value>> {
session.insert("user_id", &body.user_id).await?;
session.cycle_id().await; // CSRF protection
Ok(Json(json!({"status": "ok"})))
}Sessionextractor withget,insert,contains,destroy,cycle_idMemorySessionStorebuilt-in;SessionStoretrait for custom backends- Rolling sessions (refresh TTL on each access) by default
- Secure defaults:
HttpOnly,Secure,SameSite=Lax
🚦 Rate Limiting Strategies
Three strategies for different use cases:
use rustapi_rs::extras::rate_limit::*;
// Fixed window: 100 requests per 60 seconds
RustApi::new()
.layer(RateLimitLayer::new(100, Duration::from_secs(60))
.strategy(RateLimitStrategy::FixedWindow))
// Sliding window: smoother distribution
.layer(RateLimitLayer::new(100, Duration::from_secs(60))
.strategy(RateLimitStrategy::SlidingWindow))
// Token bucket: allows bursts
.layer(RateLimitLayer::new(100, Duration::from_secs(60))
.strategy(RateLimitStrategy::TokenBucket))- Per-IP tracking with
DashMap - Response headers:
X-RateLimit-Remaining,Retry-After - Returns
429 Too Many Requestswhen limit exceeded
🔨 New CLI Commands
cargo rustapi bench
Run the performance benchmark workflow:
cargo rustapi bench --warmup 5 --iterations 1000cargo rustapi observability
Surface observability assets and check production readiness:
cargo rustapi observability --checkChecks for production baseline docs, observability cookbook, benchmark script, and quality gate.
cargo rustapi doctor (enhanced)
Expanded environment health checks with --strict mode that fails on warnings.
📄 Enhanced Multipart Streaming
StreamingMultipart and StreamingMultipartField now support:
.bytes_read()— progress tracking.save_to(path)— stream directly to disk.save_as(path)— save with custom filename.into_uploaded_file()— convert toUploadedFile.field_count()— number of fields in the upload
📝 New Examples
Four production-ready examples added to crates/rustapi-rs/examples/:
| Example | Description |
|---|---|
auth_api.rs |
Session-based authentication with login/logout/refresh |
full_crud_api.rs |
Complete CRUD API with Arc<RwLock<HashMap>> state |
jobs_api.rs |
Background job queue with InMemoryBackend |
streaming_api.rs |
Server-sent events (SSE) streaming |
📖 New Cookbook Recipes
- Session Authentication — cookie-backed auth patterns
- Observability — monitoring and tracing setup
- Error Handling — structured error responses
- Custom Extractors — building your own extractors
- Middleware Debugging — layer inspection and troubleshooting
- Axum Migration — step-by-step migration guide from Axum
- Actix Migration — step-by-step migration guide from Actix-web
- OIDC/OAuth2 Production — production-grade OAuth2 setup
- Macro Attributes Reference — complete reference for all route macro attributes
📦 Facade Re-exports
New types available in rustapi_rs::prelude::*:
ProductionDefaultsConfig,HealthCheck,HealthCheckBuilder,HealthCheckResult,HealthStatus,HealthEndpointConfig
New modules in rustapi_rs::extras:::
session—Session,SessionLayer,SessionConfig,MemorySessionStore,SessionStore,SessionRecordrate_limit—RateLimitLayer,RateLimitStrategy
What's Changed
Full Changelog: v0.1.397...v0.1.410
v0.1.397
[0.1.397] - 2026-02-26
Added
Compile-Time Extractor Safety (rustapi-macros)
- Body-consuming extractor ordering enforced at compile time:
Json<T>,Body,ValidatedJson<T>must now be the last handler parameter — otherwise you get a clear compiler error instead of a silent runtime failure. - Descriptive error messages:
"Body-consuming extractors must be the last parameter". - Detects multiple body-consuming extractors in the same handler.
Typed Error Responses — OpenAPI Integration (rustapi-macros, rustapi-core)
- New
#[errors(404 = "Not found", 403 = "Forbidden")]attribute macro for route handlers. - Error types are automatically reflected in the OpenAPI spec with
ErrorSchemareferences. Route::error_response()builder method for programmatic error response registration.- Swagger UI now displays all possible error responses per endpoint.
Pagination & HATEOAS Helpers (rustapi-core)
Paginateextractor:?page=2&per_page=20with sensible defaults (page=1, per_page=20, max=100).Paginated<T>response wrapper: JSON body withitems/meta/_links, RFC 8288Linkheader,X-Total-Count&X-Total-Pagesheaders.CursorPaginateextractor:?cursor=abc&limit=20for cursor-based pagination.CursorPaginated<T>response wrapper:items+next_cursor+has_more.- Helper methods:
offset(),limit(),paginate(),after(),is_first_page(). - All types re-exported in the
rustapi-rsprelude.
Built-in Caching Layer (rustapi-extras)
- Full rewrite of the caching system with production-grade features:
- In-memory response cache with LRU eviction and configurable
max_entries(default: 10,000). - ETag generation via FNV-1a hash + automatic
If-None-Match→ 304 Not Modified. Cache-Controlheader awareness (no-cache,no-store).Vary-by-header cache key strategy.CacheHandlefor programmatic invalidation (by path prefix, exact key, or clear all).CacheBuilderfor ergonomic middleware configuration.
- In-memory response cache with LRU eviction and configurable
Event System & Lifecycle Hooks (rustapi-core)
EventBus: In-process pub/sub with sync and async handlers.on()for sync handlers,on_async()for async handlers.emit()(fire-and-forget) andemit_await()(wait for all handlers).handler_count()andtopics()introspection.
- Lifecycle hooks on
RustApibuilder:.on_start(async { ... })— runs before the server starts accepting connections..on_shutdown(async { ... })— runs on graceful shutdown.- Integrated into both
run()andrun_with_shutdown().
EventBusre-exported in therustapi-rsprelude.
Native Hot Reload / Watch Mode (cargo-rustapi, rustapi-core)
- Complete rewrite of
cargo rustapi watchusingnotify+notify-debouncer-mini— no morecargo-watchdependency.- 300ms debounce, configurable extension filter, smart ignore paths.
- Build-before-restart: only restarts the server if
cargo buildsucceeds. - Graceful process shutdown (kill + 5s timeout), crash detection with "watching for changes" recovery.
.hot_reload(true)builder API onRustApi— prints a dev-mode banner with watcher hints.cargo rustapi run --watch/--reload/--hotdelegates to the native watcher.
gRPC Support Published (rustapi-grpc)
- First crates.io release of
rustapi-grpc v0.1.397. run_rustapi_and_grpc()for dual HTTP + gRPC server execution.- Re-exports
tonicandprostfor ergonomic proto service integration. protocol-grpcfeature flag inrustapi-rs.
What's Changed
- fix: address review feedback - validate pagination size and update doc status by @Copilot in #110
- docs: sync to v0.1.335, add pagination recipe, and improve learning path by @Tuntii in #109
- docs: enhance learning path and fix cookbook recipes by @Tuntii in #112
- Add optional rustapi-grpc crate (tonic/prost) by @Tuntii in #118
- docs: Add Background Jobs recipe and update Learning Path by @Tuntii in #120
- docs: Enterprise Learning Path & Testing Recipe by @Tuntii in #121
- core: stabilize facade API surface, feature taxonomy, and public-api CI gate by @Tuntii in #122
- docs: Add Phase 5 (Specialized Skills) and recipes for gRPC, SSR, and AI by @Tuntii in #123
- docs: Fix SSR recipe and update cookbook index by @Tuntii in #124
- docs: improve cookbook and learning path by @Tuntii in #125
- docs: Cookbook and Learning Path Improvements by @Tuntii in #126
- docs: continuous improvement and accuracy fixes by @Tuntii in #129
- docs: cookbook expansion and learning path improvements by @Tuntii in #132
- Fix review feedback: deduplication, pagination validation, lifecycle error handling, cache correctness by @Copilot in #140
- Add lifecycle hooks, pagination, and cache by @Tuntii in #139
Full Changelog: v0.1.335...v0.1.397
V0.1.335
RustAPI Release History
v0.1.333 - Quick Wins + Must-Have Completion (2026-02-08)
This release combines dependency surface cleanup, runtime completions, and documentation alignment in one focused quick-wins iteration.
Highlights
- True dual-stack runtime completed:
RustApi::run_dual_stacknow runs HTTP/1.1 (TCP) and HTTP/3 (QUIC/UDP) simultaneously. - WebSocket permessage-deflate negotiation completed: real extension parsing and parameter negotiation added for
Sec-WebSocket-Extensions. - OpenAPI ref integrity coverage strengthened: component traversal validation now includes response/requestBody/header/callback paths with tests.
- Async validation context from app state:
AsyncValidatedJsonnow uses state-providedValidationContextbehavior with verified coverage. - Native OpenAPI + validation documentation alignment: architecture docs are synced to OpenAPI 3.1 and v2-native validation direction.
- Dependency footprint reduced (quick wins): unused/overly broad dependencies and feature sets were tightened, reducing lockfile surface.
Technical Details
crates/rustapi-core/src/app.rs:run_dual_stackimplementationcrates/rustapi-core/src/server.rs:Server::from_sharedfor shared app statecrates/rustapi-ws/src/upgrade.rs: permessage-deflate parsing/negotiationcrates/rustapi-ws/src/compression.rs: negotiation test updatescrates/rustapi-openapi/src/tests.rs: reference traversal coverage testdocs/ARCHITECTURE.md,docs/cookbook/src/architecture/system_overview.md,crates/rustapi-openapi/README.md: architecture/docs alignment
Validation
cargo test -p rustapi-openapicargo test -p rustapi-wscargo test -p rustapi-core test_async_validated_json_with_state_contextcargo check -p rustapi-core --features http3
Commit References
ca238acchore(quick-wins): reduce dependency surface and align native OpenAPI docsdcb0e8bfeat(core/ws/openapi): complete quick-wins must-haves
What's Changed
- Update documentation and workspace versions to 0.1.300 by @Tuntii in #103
- Extract validators from App State in AsyncValidatedJson by @Tuntii in #104
- ⚡ Optimize RegexRule compilation by @Tuntii in #102
- Validate references in all OpenAPI spec components by @Tuntii in #101
- ⚡ Optimize FileAuditStore::log_async to use spawn_blocking by @Tuntii in #100
- ⚡ Fix Head-of-Line Blocking in InMemory Job Backend by @Tuntii in #99
- Bump opentelemetry from 0.22.0 to 0.31.0 by @dependabot[bot] in #95
- Bump opentelemetry-semantic-conventions from 0.14.0 to 0.31.0 by @dependabot[bot] in #92
- docs: update versions to 0.1.300 and expand testing documentation by @Tuntii in #105
- Update Cookbook Documentation for v0.1.300 by @Tuntii in #106
- chore(quick-wins): reduce dependency surface and align native OpenAPI… by @Tuntii in #107
- feat(core/openapi/ws): dual-stack (H1+H3) runtime, async validation context, OpenAPI ref integrity, WS permessage-deflate negotiation, aligned docs by @Tuntii in #108
Full Changelog: v0.1.300...v0.1.335