One story: define a handler → get OpenAPI → run probes → optional MCP / deploy.
Everything else (JWT, jobs, WS, gRPC, full extras) is a branch off this path. Start here.
| Step | What you get |
|---|---|
1. Handler + Schema |
Typed JSON response |
2. RustApi::auto() |
Route discovery, Swagger UI /docs, spec /docs/openapi.json |
3. production_defaults |
Request IDs, tracing spans, /live /ready /health |
| 4. (optional) MCP | Same routes as agent tools |
| 5. (optional) Cloud / Docker | Ship the binary |
git clone https://github.com/Tuntii/RustAPI.git
cd RustAPI
cargo run -p rustapi-rs --example golden_pathIn another terminal:
curl -s http://127.0.0.1:8080/api/v1/ping
# {"status":"ok"}
curl -s http://127.0.0.1:8080/live
# healthy probe JSON
# OpenAPI paths include /api/v1/ping
curl -s http://127.0.0.1:8080/docs/openapi.json | head -c 400
# Browser
# http://127.0.0.1:8080/docsSource: crates/rustapi-rs/examples/golden_path.rs
cargo new hello-rustapi && cd hello-rustapi
cargo add rustapi-rs
cargo add tokio --features macros,rt-multi-thread
cargo add tracing-subscriber --features env-filtersrc/main.rs:
use rustapi_rs::prelude::*;
use tokio::signal;
#[derive(Debug, Serialize, Schema)]
struct PingResponse {
status: &'static str,
}
#[rustapi_rs::get("/api/v1/ping")]
#[rustapi_rs::tag("public")]
#[rustapi_rs::summary("Ping")]
async fn ping() -> Json<PingResponse> {
Json(PingResponse { status: "ok" })
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
tracing_subscriber::fmt::init();
RustApi::auto()
.production_defaults("hello-rustapi")
.run_with_shutdown("127.0.0.1:8080", async {
signal::ctrl_c().await.ok();
})
.await
}cargo run
curl -s http://127.0.0.1:8080/api/v1/ping
# open http://127.0.0.1:8080/docsCrate alias (optional): shorter macros like FastAPI-style imports:
[dependencies]
api = { package = "rustapi-rs", version = "0.1" }use api::prelude::*;
#[api::get("/api/v1/ping")]
#[api::tag("public")]
async fn ping() -> Json<PingResponse> { /* ... */ }Prefer slim features in real services (default-features = false, features = ["core"]) — see Getting Started.
#[rustapi_rs::get("/...")] registers the handler at link time and feeds the OpenAPI operation (path, tags, response schemas).
.route(path, get(handler)) is valid for dynamic wiring, but the golden path uses macros so /docs is not an empty shell.
| Capability | Endpoints / behavior |
|---|---|
| Request IDs | x-request-id on responses |
| Tracing | Per-request spans (with your subscriber) |
| Probes | GET /live, GET /ready, GET /health |
| Service name | Attached to logs / health metadata |
Details: Production Baseline
Ship checklist: Production Checklist
Set RUSTAPI_ENV=production to mask 5xx detail bodies while keeping error_id for log correlation.
Expose the same tagged routes as MCP tools (feature protocol-mcp):
use rustapi_rs::protocol::mcp::{McpConfig, McpServer, run_rustapi_and_mcp_with_shutdown};
// after building the same auto() app pattern — see mcp_tools example
let mcp = McpServer::from_rustapi(&app, McpConfig::new().allowed_tags(["public"]));In-repo: cargo run -p rustapi-rs --example mcp_tools --features protocol-mcp
Cookbook: MCP Integration (if present) · crate notes under cookbook rustapi_mcp
CLI (any OpenAPI → MCP):
cargo install cargo-rustapi
cargo rustapi mcp generate --helpLocal binary / container: Deployment recipe
Managed:
cargo install cargo-rustapi
cargo rustapi login
cargo rustapi deploy cloudGuide: RustAPI Cloud
- Enable
fullfeature for production compiles - Skip probes and ship behind a load balancer
- Treat every recipe (JWT, jobs, WS) as required core
- Promise HTTP/2/3 edge behavior without reading Performance Benchmarks methodology
| Doc | Role |
|---|---|
| Getting Started | Longer tutorial + feature table |
| Cookbook Quickstart | CLI cargo rustapi new path |
| docs hub | Full index |
| rustapi-rs-examples | Larger sample apps |