A minimal example demonstrating Cross-Origin Resource Sharing (CORS) configuration with RustAPI.
📖 Cookbook: CORS Configuration
This example shows how to configure CORS for your RustAPI application, enabling cross-origin requests from web browsers. Essential for:
- Frontend applications on different domains
- Single Page Applications (SPAs)
- Mobile apps using web views
- Third-party API integrations
- Rust 1.70+
- Understanding of CORS concepts
- Basic hello-world knowledge
| Feature | Description |
|---|---|
CorsLayer::permissive() |
Allow all origins (development) |
CorsLayer::new() |
Custom CORS configuration |
| Layer composition | Multiple middleware layers |
# Run the example
cargo run -p cors-test
# Server starts at http://127.0.0.1:3030| Method | Path | Description |
|---|---|---|
| GET | / |
Hello message with CORS headers |
# Simple request
curl -v http://127.0.0.1:3030/
# Preflight request (OPTIONS)
curl -v -X OPTIONS http://127.0.0.1:3030/ \
-H "Origin: http://localhost:3000" \
-H "Access-Control-Request-Method: GET"
# Check response headers for:
# Access-Control-Allow-Origin: *
# Access-Control-Allow-Methods: GET, POST, ...
# Access-Control-Allow-Headers: ...// Open browser console on any page
fetch('http://127.0.0.1:3030/')
.then(r => r.text())
.then(console.log);
// Should work without CORS errorsRustApi::new()
.route("/", get(hello))
.layer(CorsLayer::permissive()) // Allow all origins
.run("127.0.0.1:3030")
.awaitCorsLayer::permissive() allows:
- All origins (
*) - All standard methods
- All headers
- Credentials
use rustapi_rs::middleware::CorsLayer;
let cors = CorsLayer::new()
.allow_origins([
"https://example.com",
"https://app.example.com",
])
.allow_methods(["GET", "POST", "PUT", "DELETE"])
.allow_headers(["Content-Type", "Authorization"])
.allow_credentials(true)
.max_age(3600); // Cache preflight for 1 hour
RustApi::new()
.route("/", get(hello))
.layer(cors)
.run("127.0.0.1:3030")
.await| Option | Description | Example |
|---|---|---|
allow_origins() |
Allowed origin domains | ["https://example.com"] |
allow_methods() |
Allowed HTTP methods | ["GET", "POST"] |
allow_headers() |
Allowed request headers | ["Content-Type"] |
expose_headers() |
Headers client can access | ["X-Custom-Header"] |
allow_credentials() |
Allow cookies/auth | true |
max_age() |
Preflight cache duration | 3600 (seconds) |
CorsLayer::new()
.allow_origins(["https://app.example.com"])
.allow_methods(["GET", "POST", "PUT", "DELETE"])
.allow_headers(["Content-Type", "Authorization"])
.allow_credentials(true)CorsLayer::new()
.allow_origins(["*"]) // Any origin
.allow_methods(["GET"])
.max_age(86400) // Cache for 24 hoursCorsLayer::new()
.allow_origins([
"https://web.example.com",
"https://admin.example.com",
"http://localhost:3000", // Development
])This example also demonstrates combining multiple layers:
RustApi::new()
.route("/", get(hello))
.layer(CorsLayer::permissive())
.layer(RequestIdLayer::new())
.layer(TracingLayer::new())
.layer(RateLimitLayer::new(100, Duration::from_secs(60)))
.run("127.0.0.1:3030")
.awaitExecution order (outside → inside):
- CORS (handles preflight)
- Request ID (adds tracking)
- Tracing (logs request)
- Rate Limit (checks limits)
- Handler
[dependencies]
rustapi-rs = { version = "0.2", features = ["cors", "rate-limit"] }
tokio = { version = "1", features = ["full"] }
serde = "1"- Check
Access-Control-Allow-Originheader matches your origin - Ensure preflight (OPTIONS) is handled
- Verify
allow_credentials()if using cookies
// Must specify exact origins (not "*") when using credentials
CorsLayer::new()
.allow_origins(["https://specific-domain.com"]) // Not "*"
.allow_credentials(true)CorsLayer::new()
.expose_headers(["X-Custom-Header", "X-Request-Id"])- middleware-chain — Custom middleware creation
- auth-api — CORS with authentication
- FEATURES.md — CORS feature reference
- RustAPI Cookbook — Full documentation