route_controller
Generate Axum routers from controller-style implementations with declarative extractors
Features
- Clean controller-style API similar to Routing Controller (JS) or Rocket
- Route prefixing for organizing endpoints
- Declarative extractor syntax with
extract()attribute - Built-in extractors:
- Body extractors:
Json,Form,Bytes,Text,Html,Xml,JavaScript - URL extractors:
Path,Query - State extractor:
State
- Body extractors:
- Optional extractors (with feature flags):
HeaderParam- Extract from HTTP headers (requiresheadersfeature)CookieParam- Extract from cookies (requirescookiesfeature)SessionParam- Extract from session storage (requiressessionsfeature)
- Response header support:
header()andcontent_type()attributes- Controller-level headers: Apply headers to all routes in a controller
- Route-level override: Route headers override controller headers with the same name
- Middleware support at the controller level
- HTTP method attributes:
#[get],#[post],#[put],#[delete],#[patch],#[head],#[options],#[trace]
Installation
[]
= "0.2.0"
= "0.8" # Also works with axum 0.7 and earlier versions
= { = "1", = ["full"] }
= { = "1.0", = ["derive"] }
Path Parameter Syntax
The path parameter syntax depends on your Axum version:
- Axum 0.8+: Use curly braces
{id}for path parameters
async
- Axum 0.7 and earlier: Use colon syntax
:idfor path parameters
async
Optional Dependencies
For additional extractors, enable features and add required dependencies:
[]
= { = "0.2.0", = ["headers", "cookies", "sessions"] }
= { = "0.12", = ["cookie"] } # Required for cookies
= "0.14" # Required for sessions
Quick Start
use ;
use ;
;
async
Controller Types
The extract() Attribute
Use the extract() attribute to specify how each parameter should be extracted from the request. The order of extractors in the attribute can differ from the parameter order:
Available Extractors
Request Body Extractors
-
Json- Extract JSON request body:extract(data = Json)- Type: Any deserializable struct (
T where T: serde::Deserialize) - Content-Type:
application/json
- Type: Any deserializable struct (
-
Form- Extract form data (form-data or x-www-form-urlencoded):extract(data = Form)- Type: Any deserializable struct (
T where T: serde::Deserialize) - Content-Type:
application/x-www-form-urlencodedormultipart/form-data
- Type: Any deserializable struct (
-
Bytes- Extract raw binary data:extract(data = Bytes)- Type:
Vec<u8> - Useful for file uploads, binary protocols, etc.
- Type:
-
Text- Extract plain text:extract(content = Text)- Type:
String - Content-Type:
text/plain
- Type:
-
Html- Extract HTML content:extract(content = Html)- Type:
String - Content-Type:
text/html
- Type:
-
Xml- Extract XML content:extract(content = Xml)- Type:
String - Content-Type:
application/xmlortext/xml
- Type:
-
JavaScript- Extract JavaScript content:extract(code = JavaScript)- Type:
String - Content-Type:
application/javascriptortext/javascript
- Type:
URL Extractors
Path- Extract path parameters:extract(id = Path)Query- Extract query parameters:extract(params = Query)
Other Extractors
State- Extract application state:extract(state = State)
Feature-Gated Extractors
Enable additional extractors with Cargo features:
[]
= { = "0.2.0", = ["headers", "cookies", "sessions"] }
= { = "0.12", = ["cookie"] } # Required for cookies
= "0.14" # Required for sessions
-
HeaderParam- Extract from HTTP headers (requiresheadersfeature)async -
CookieParam- Extract from cookies (requirescookiesfeature +axum-extra)async -
SessionParam- Extract from session storage (requiressessionsfeature +tower-sessions)async
Using State
Extract application state in your handlers using the State extractor:
use Arc;
use RwLock;
;
async
Body Extractor Examples
Form Data
Handle form submissions with the Form extractor:
Test with:
Binary Data
Handle file uploads or binary data with the Bytes extractor:
Text Content Types
Handle various text-based content types:
Response Headers
Add custom headers to your responses using the header() and content_type() attributes at both the controller and route levels.
Controller-Level Headers
Apply headers to all routes in a controller. Route-level headers with the same name will override controller-level headers:
Route-Level Headers
Multiple Headers
Content-Type Header
Set content-type at controller or route level:
// Controller-level content-type applies to all routes
Combining Controller and Route Headers
Controller headers provide a base set of headers, and routes can override or extend them:
// Controller provides base headers and content-type
Test with:
# Check inherited headers
# Output: x-api-version: 1.0, x-service: my-api, content-type: application/json
# Check overridden headers
# Output: x-api-version: 2.0, x-service: my-api, x-rate-limit: 100
Examples
The crate includes 15 comprehensive examples demonstrating different features:
# 1. Basic routing with different HTTP methods (GET, POST, PUT, DELETE)
# 2. Path parameter extraction
# 3. Query parameter extraction
# 4. JSON body extraction
# 5. Form data handling (form-data and x-www-form-urlencoded)
# 6. Text body extraction
# 7. Binary data (bytes) handling
# 8. Header extraction (requires 'headers' feature)
# 9. Cookie handling (requires 'cookies' feature)
# 10. Session management (requires 'sessions' feature)
# 11. Application state management
# 12. Response headers and content types
# 13. Middleware application
# 14. Mixed extractors (Path + Query + Json)
# 15. Multiple controllers with merged routers
Each example includes:
- Clear comments explaining the feature
- Test commands using curl
- Working code that can be run immediately
With Middleware
Apply middleware at the controller level:
use ;
async
You can also apply multiple middlewares:
See examples/13_middleware.rs for a complete example.
Verbose Logging
Enable verbose logging during compilation by setting the ROUTE_CONTROLLER_VERBOSE environment variable:
ROUTE_CONTROLLER_VERBOSE=1
ROUTE_CONTROLLER_VERBOSE=1
This shows detailed information about route registration during compilation.
License
MIT