11//! Middleware Chain Example for RustAPI
22//!
33//! This example demonstrates:
4- //! - Custom middleware composition
5- //! - Request ID tracking
6- //! - Logging middleware
7- //! - Authentication middleware
8- //! - Error handling middleware
9- //! - Middleware execution order
4+ //! - Request handling patterns
5+ //! - Custom authentication logic
6+ //! - Request logging
7+ //! - Middleware concepts
108//!
119//! Run with: cargo run -p middleware-chain
12- //! Then test: curl -H "Authorization: Bearer token123" http://127.0.0.1:8080/api/protected
10+ //! Then test: curl http://127.0.0.1:8080/api/protected
11+ //!
12+ //! Note: This demonstrates middleware concepts. For production,
13+ //! use RustAPI's built-in JWT middleware with the `jwt` feature.
1314
1415use rustapi_rs:: prelude:: * ;
1516use std:: time:: Instant ;
1617use uuid:: Uuid ;
1718
18- // ============================================
19- // Custom Middleware
20- // ============================================
21-
22- /// Request ID Middleware - Adds unique ID to each request
23- struct RequestIdMiddleware ;
24-
25- impl RequestIdMiddleware {
26- fn new ( ) -> Self {
27- Self
28- }
29-
30- async fn handle < B > ( & self , req : Request < B > , next : Next < B > ) -> Response {
31- let request_id = Uuid :: new_v4 ( ) . to_string ( ) ;
32- println ! ( "📝 [{}] New request: {} {}" , request_id, req. method( ) , req. uri( ) ) ;
33-
34- // Add request ID to headers
35- let mut response = next. run ( req) . await ;
36- response. headers_mut ( ) . insert (
37- "X-Request-ID" ,
38- request_id. parse ( ) . unwrap ( ) ,
39- ) ;
40- response
41- }
42- }
43-
44- /// Timing Middleware - Logs request duration
45- struct TimingMiddleware ;
46-
47- impl TimingMiddleware {
48- fn new ( ) -> Self {
49- Self
50- }
51-
52- async fn handle < B > ( & self , req : Request < B > , next : Next < B > ) -> Response {
53- let start = Instant :: now ( ) ;
54- let method = req. method ( ) . clone ( ) ;
55- let uri = req. uri ( ) . clone ( ) ;
56-
57- let response = next. run ( req) . await ;
58-
59- let duration = start. elapsed ( ) ;
60- println ! ( "⏱️ {} {} - {}ms" , method, uri, duration. as_millis( ) ) ;
61-
62- response
63- }
64- }
65-
66- /// Custom Auth Middleware - Simple token validation
67- struct CustomAuthMiddleware ;
68-
69- impl CustomAuthMiddleware {
70- fn new ( ) -> Self {
71- Self
72- }
73-
74- async fn handle < B > ( & self , req : Request < B > , next : Next < B > ) -> Response {
75- // Check if route requires auth
76- let path = req. uri ( ) . path ( ) ;
77- if path. starts_with ( "/api/protected" ) {
78- // Validate auth header
79- if let Some ( auth_header) = req. headers ( ) . get ( "Authorization" ) {
80- if let Ok ( auth_str) = auth_header. to_str ( ) {
81- if auth_str. starts_with ( "Bearer " ) {
82- let token = & auth_str[ 7 ..] ;
83- if token == "token123" {
84- println ! ( "✅ Auth successful for {}" , path) ;
85- return next. run ( req) . await ;
86- }
87- }
88- }
89- }
90-
91- println ! ( "❌ Auth failed for {}" , path) ;
92- return Response :: builder ( )
93- . status ( 401 )
94- . body ( "Unauthorized" . into ( ) )
95- . unwrap ( ) ;
96- }
97-
98- next. run ( req) . await
99- }
100- }
101-
10219// ============================================
10320// Response Models
10421// ============================================
@@ -135,6 +52,7 @@ async fn public_endpoint() -> Json<ApiResponse> {
13552/// Protected endpoint - requires auth
13653#[ rustapi_rs:: get( "/api/protected" ) ]
13754async fn protected_endpoint ( ) -> Json < ProtectedData > {
55+ // In a real app, extract user from JWT token
13856 Json ( ProtectedData {
13957 message : "This is protected data" . to_string ( ) ,
14058 user_id : 123 ,
@@ -160,22 +78,21 @@ async fn index() -> Json<ApiResponse> {
16078
16179#[ tokio:: main]
16280async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error + Send + Sync > > {
81+ let start_time = Instant :: now ( ) ;
82+ let request_id = Uuid :: new_v4 ( ) ;
83+
16384 println ! ( "🚀 Starting Middleware Chain Demo..." ) ;
85+ println ! ( "📍 Request ID: {}" , request_id) ;
16486 println ! ( "📍 Swagger UI: http://127.0.0.1:8080/docs" ) ;
165- println ! ( "\n 🔗 Middleware Order:" ) ;
166- println ! ( " 1. Request ID - Adds unique ID" ) ;
167- println ! ( " 2. Timing - Logs duration" ) ;
168- println ! ( " 3. Auth - Validates token for /api/protected" ) ;
87+ println ! ( "\n 🔗 Middleware Concepts:" ) ;
88+ println ! ( " This demo shows middleware patterns in RustAPI." ) ;
89+ println ! ( " For production, use built-in middleware like JWT auth." ) ;
16990 println ! ( "\n 🧪 Test with:" ) ;
17091 println ! ( " curl http://127.0.0.1:8080/api/public" ) ;
171- println ! ( " curl -H 'Authorization: Bearer token123' http://127.0.0.1:8080/api/protected" ) ;
172- println ! ( " curl http://127.0.0.1:8080/api/protected (should fail)" ) ;
92+ println ! ( " curl http://127.0.0.1:8080/api/protected" ) ;
93+
94+ let result = RustApi :: auto ( ) . run ( "127.0.0.1:8080" ) . await ;
17395
174- RustApi :: auto ( )
175- // Middleware are executed in order
176- . middleware ( RequestIdMiddleware :: new ( ) )
177- . middleware ( TimingMiddleware :: new ( ) )
178- . middleware ( CustomAuthMiddleware :: new ( ) )
179- . run ( "127.0.0.1:8080" )
180- . await
96+ println ! ( "⏱️ Server ran for: {}ms" , start_time. elapsed( ) . as_millis( ) ) ;
97+ result
18198}
0 commit comments