pub struct App { /* private fields */ }
Expand description
The main application builder for Torch web framework.
App
is the central component that ties together routing, middleware, state management,
and server configuration. It follows a builder pattern for easy configuration and
provides a fluent API for defining routes and middleware.
§Examples
§Basic Usage
use torch_web::{App, Request, Response};
let app = App::new()
.get("/", |_req: Request| async {
Response::ok().body("Hello, World!")
})
.post("/users", |_req: Request| async {
Response::created().body("User created")
});
§With Middleware
use torch_web::{App, Request, Response};
let app = App::new()
.middleware(torch_web::middleware::logger())
.middleware(torch_web::middleware::cors())
.get("/api/users", |_req: Request| async {
Response::ok().json(&serde_json::json!({"users": []}))
});
§With Application State
use torch_web::{App, Request, Response, extractors::State};
use std::sync::Arc;
#[derive(Clone)]
struct AppState {
counter: Arc<std::sync::atomic::AtomicU64>,
}
let state = AppState {
counter: Arc::new(std::sync::atomic::AtomicU64::new(0)),
};
let app = App::new()
.with_state(state)
.get("/count", |State(state): State<AppState>| async move {
let count = state.counter.load(std::sync::atomic::Ordering::SeqCst);
Response::ok().body(format!("Count: {}", count))
});
§Production-Ready Configuration
use torch_web::App;
let app = App::with_defaults() // Includes security, monitoring, CORS
.get("/health", |_req| async {
Response::ok().json(&serde_json::json!({"status": "healthy"}))
});
Implementations§
Source§impl App
Convenience methods for App to add documented endpoints
impl App
Convenience methods for App to add documented endpoints
Sourcepub fn documented_get<H, T>(
self,
path: &str,
handler: H,
doc: EndpointDoc,
) -> Selfwhere
H: Handler<T>,
pub fn documented_get<H, T>(
self,
path: &str,
handler: H,
doc: EndpointDoc,
) -> Selfwhere
H: Handler<T>,
Add a documented GET endpoint
Sourcepub fn documented_post<H, T>(
self,
path: &str,
handler: H,
doc: EndpointDoc,
) -> Selfwhere
H: Handler<T>,
pub fn documented_post<H, T>(
self,
path: &str,
handler: H,
doc: EndpointDoc,
) -> Selfwhere
H: Handler<T>,
Add a documented POST endpoint
Source§impl App
impl App
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new application instance with default configuration.
This initializes an empty application with:
- A new router with no routes
- An empty middleware stack
- Default error pages
- Empty state map
§Examples
use torch_web::App;
let app = App::new();
Sourcepub fn with_state<T>(self, state: T) -> Self
pub fn with_state<T>(self, state: T) -> Self
Adds application state that can be accessed in handlers via the State
extractor.
Application state allows you to share data across all handlers, such as database
connections, configuration, or any other shared resources. The state must implement
Clone + Send + Sync + 'static
.
§Type Parameters
T
- The type of state to add. Must beClone + Send + Sync + 'static
.
§Examples
use torch_web::{App, Request, Response, extractors::State};
use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Clone)]
struct AppState {
counter: Arc<AtomicU64>,
}
let state = AppState {
counter: Arc::new(AtomicU64::new(0)),
};
let app = App::new()
.with_state(state)
.get("/count", |State(state): State<AppState>| async move {
let count = state.counter.fetch_add(1, Ordering::SeqCst);
Response::ok().body(format!("Count: {}", count))
});
Sourcepub fn middleware<M>(self, middleware: M) -> Selfwhere
M: Middleware,
pub fn middleware<M>(self, middleware: M) -> Selfwhere
M: Middleware,
Adds middleware to the application’s middleware stack.
Middleware is executed in the order it’s added, wrapping the final route handler. Each middleware can modify the request before it reaches the handler and/or modify the response before it’s sent to the client.
§Type Parameters
M
- The middleware type. Must implement theMiddleware
trait.
§Examples
use torch_web::{App, middleware};
let app = App::new()
.middleware(middleware::logger())
.middleware(middleware::cors())
.get("/", |_req| async { Response::ok().body("Hello!") });
§Custom Middleware
use torch_web::{App, Request, Response, middleware::Middleware};
use std::pin::Pin;
use std::future::Future;
struct CustomMiddleware;
impl Middleware for CustomMiddleware {
fn call(
&self,
req: Request,
next: Box<dyn Fn(Request) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>> + Send + Sync>,
) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>> {
Box::pin(async move {
// Modify request here
let mut response = next(req).await;
// Modify response here
response = response.header("X-Custom", "middleware");
response
})
}
}
let app = App::new().middleware(CustomMiddleware);
Sourcepub fn route<H, T>(self, method: Method, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
pub fn route<H, T>(self, method: Method, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
Registers a route for any HTTP method with the specified path and handler.
This is the most flexible route registration method that allows you to specify
any HTTP method. For common methods, consider using the convenience methods
like get
, post
, put
, etc.
§Parameters
method
- The HTTP method to match (GET, POST, PUT, DELETE, etc.)path
- The URL path pattern to match. Supports parameters like/users/:id
handler
- The handler function to execute when the route matches
§Path Parameters
Paths can include parameters using the :name
syntax:
/users/:id
matches/users/123
and capturesid = "123"
/posts/:id/comments/:comment_id
captures multiple parameters- Use the
Path
extractor to access parameters in handlers
§Examples
use torch_web::{App, Request, Response, Method};
let app = App::new()
.route(Method::GET, "/", |_req: Request| async {
Response::ok().body("Hello, World!")
})
.route(Method::POST, "/users", |_req: Request| async {
Response::created().body("User created")
});
Sourcepub fn get<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
pub fn get<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
Registers a GET route handler.
GET requests are typically used for retrieving data and should be idempotent (safe to repeat). Perfect for serving web pages, API endpoints that fetch data, and static resources.
§Parameters
path
- The URL path pattern to matchhandler
- The handler function to execute
§Examples
use torch_web::{App, Request, Response, extractors::Path};
let app = App::new()
.get("/", |_req: Request| async {
Response::ok().body("Welcome to Torch!")
})
.get("/users/:id", |Path(id): Path<u32>| async move {
Response::ok().body(format!("User ID: {}", id))
})
.get("/api/users", |_req: Request| async {
Response::ok().json(&serde_json::json!({"users": []}))
});
Sourcepub fn post<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
pub fn post<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
Registers a POST route handler.
POST requests are typically used for creating new resources or submitting data. They are not idempotent and can have side effects.
§Parameters
path
- The URL path pattern to matchhandler
- The handler function to execute
§Examples
use torch_web::{App, Request, Response, extractors::Json};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct CreateUser {
name: String,
email: String,
}
let app = App::new()
.post("/users", |Json(user): Json<CreateUser>| async move {
// Create user logic here
Response::created().json(&user)
})
.post("/login", |_req: Request| async {
Response::ok().body("Login successful")
});
Sourcepub fn put<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
pub fn put<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
Registers a PUT route handler.
PUT requests are typically used for updating entire resources or creating resources with a specific ID. They should be idempotent.
§Parameters
path
- The URL path pattern to matchhandler
- The handler function to execute
§Examples
use torch_web::{App, Request, Response, extractors::{Path, Json}};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct UpdateUser {
name: String,
email: String,
}
let app = App::new()
.put("/users/:id", |Path(id): Path<u32>, Json(user): Json<UpdateUser>| async move {
// Update user logic here
Response::ok().json(&user)
});
Sourcepub fn delete<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
pub fn delete<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
Registers a DELETE route handler.
DELETE requests are used for removing resources. They should be idempotent (deleting a non-existent resource should not cause an error).
§Parameters
path
- The URL path pattern to matchhandler
- The handler function to execute
§Examples
use torch_web::{App, Request, Response, extractors::Path};
let app = App::new()
.delete("/users/:id", |Path(id): Path<u32>| async move {
// Delete user logic here
Response::no_content()
})
.delete("/posts/:id", |Path(id): Path<u32>| async move {
Response::ok().body(format!("Deleted post {}", id))
});
Sourcepub fn patch<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
pub fn patch<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
Registers a PATCH route handler.
PATCH requests are used for partial updates to resources. Unlike PUT, PATCH only updates the specified fields rather than replacing the entire resource.
§Parameters
path
- The URL path pattern to matchhandler
- The handler function to execute
§Examples
use torch_web::{App, Request, Response, extractors::{Path, Json}};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct PatchUser {
name: Option<String>,
email: Option<String>,
}
let app = App::new()
.patch("/users/:id", |Path(id): Path<u32>, Json(patch): Json<PatchUser>| async move {
// Partial update logic here
Response::ok().json(&patch)
});
Sourcepub fn options<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
pub fn options<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
Registers an OPTIONS route handler.
OPTIONS requests are typically used for CORS preflight requests to check what methods and headers are allowed for cross-origin requests.
§Parameters
path
- The URL path pattern to matchhandler
- The handler function to execute
§Examples
use torch_web::{App, Request, Response};
let app = App::new()
.options("/api/*", |_req: Request| async {
Response::ok()
.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
.header("Access-Control-Allow-Headers", "Content-Type, Authorization")
.body("")
});
Sourcepub fn head<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
pub fn head<H, T>(self, path: &str, handler: H) -> Selfwhere
H: Handler<T>,
Registers a HEAD route handler.
HEAD requests are identical to GET requests except that the server must not return a message body. They’re useful for checking if a resource exists or getting metadata without downloading the full content.
§Parameters
path
- The URL path pattern to matchhandler
- The handler function to execute
§Examples
use torch_web::{App, Request, Response};
let app = App::new()
.head("/users/:id", |_req: Request| async {
// Check if user exists and return appropriate headers
Response::ok()
.header("Content-Type", "application/json")
.header("Content-Length", "42")
});
Sourcepub fn not_found<H, T>(self, handler: H) -> Selfwhere
H: Handler<T>,
pub fn not_found<H, T>(self, handler: H) -> Selfwhere
H: Handler<T>,
Sets a custom handler for requests that don’t match any registered route.
By default, unmatched requests return a 404 Not Found response. This method allows you to customize that behavior with your own handler.
§Parameters
handler
- The handler function to execute for unmatched routes
§Examples
use torch_web::{App, Request, Response};
let app = App::new()
.get("/", |_req: Request| async {
Response::ok().body("Home")
})
.not_found(|req: Request| async move {
Response::not_found()
.body(format!("Sorry, {} was not found", req.path()))
});
Sourcepub fn mount(self, prefix: &str, other: Router) -> Self
pub fn mount(self, prefix: &str, other: Router) -> Self
Mounts another router at a specific path prefix.
This allows you to modularize your application by creating separate routers for different parts of your API and then mounting them under different prefixes. All routes from the mounted router will be prefixed with the specified path.
§Parameters
prefix
- The path prefix to mount the router under (e.g., “/api/v1”)other
- The router to mount
§Examples
use torch_web::{App, Router, Request, Response};
// Create a router for user-related endpoints
let mut user_router = Router::new();
user_router.get("/", |_req: Request| async {
Response::ok().body("List users")
});
user_router.get("/:id", |_req: Request| async {
Response::ok().body("Get user")
});
// Mount it under /api/users
let app = App::new()
.get("/", |_req: Request| async {
Response::ok().body("Home")
})
.mount("/api/users", user_router);
// Now you have:
// GET / -> "Home"
// GET /api/users/ -> "List users"
// GET /api/users/:id -> "Get user"
Sourcepub fn error_pages(self, error_pages: ErrorPages) -> Self
pub fn error_pages(self, error_pages: ErrorPages) -> Self
Configures custom error pages for the application.
This replaces the default error page configuration with a custom one. Use this when you want full control over error page rendering.
§Parameters
error_pages
- The custom error pages configuration
§Examples
use torch_web::{App, ErrorPages};
let custom_errors = ErrorPages::new()
.custom_404("<h1>Page Not Found</h1>".to_string())
.custom_500("<h1>Server Error</h1>".to_string());
let app = App::new()
.error_pages(custom_errors);
Sourcepub fn custom_404(self, html: String) -> Self
pub fn custom_404(self, html: String) -> Self
Sets a custom HTML template for 404 Not Found errors.
This is a convenience method for setting just the 404 error page without having to create a full ErrorPages configuration.
§Parameters
html
- The HTML content to display for 404 errors
§Examples
use torch_web::App;
let app = App::new()
.custom_404(r#"
<html>
<body>
<h1>🔥 Torch doesn't know this route!</h1>
<p>The page you're looking for doesn't exist.</p>
</body>
</html>
"#.to_string());
Sourcepub fn custom_500(self, html: String) -> Self
pub fn custom_500(self, html: String) -> Self
Sets a custom HTML template for 500 Internal Server Error responses.
This is a convenience method for setting just the 500 error page without having to create a full ErrorPages configuration.
§Parameters
html
- The HTML content to display for 500 errors
§Examples
use torch_web::App;
let app = App::new()
.custom_500(r#"
<html>
<body>
<h1>🔥 Something went wrong!</h1>
<p>We're working to fix this issue.</p>
</body>
</html>
"#.to_string());
Sourcepub fn plain_error_pages(self) -> Self
pub fn plain_error_pages(self) -> Self
Disables the default error page styling and uses plain HTML.
By default, Torch adds CSS styling to error pages. This method disables that styling if you prefer plain HTML or want to add your own styling.
§Examples
use torch_web::App;
let app = App::new()
.plain_error_pages()
.custom_404("<h1>Not Found</h1>".to_string());
Sourcepub fn websocket<F, Fut>(self, _path: &str, _handler: F) -> Self
pub fn websocket<F, Fut>(self, _path: &str, _handler: F) -> Self
No-op WebSocket method when the websocket feature is disabled.
This method exists to provide a consistent API regardless of whether
the websocket
feature is enabled. When the feature is disabled,
this method does nothing and returns the app unchanged.
Sourcepub async fn listen(
self,
addr: &str,
) -> Result<(), Box<dyn Error + Send + Sync>>
pub async fn listen( self, addr: &str, ) -> Result<(), Box<dyn Error + Send + Sync>>
Starts the HTTP server and begins listening for incoming requests.
This method consumes the App
and starts the server on the specified address.
The server will run until the process is terminated or an error occurs.
§Parameters
addr
- The address to bind to (e.g., “127.0.0.1:3000” or “0.0.0.0:8080”)
§Returns
Returns Ok(())
if the server shuts down gracefully, or an error if
the server fails to start or encounters a fatal error.
§Examples
§Basic Server
use torch_web::{App, Request, Response};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let app = App::new()
.get("/", |_req: Request| async {
Response::ok().body("Hello, World!")
});
app.listen("127.0.0.1:3000").await
}
§Production Server
use torch_web::App;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let app = App::with_defaults()
.get("/health", |_req| async {
Response::ok().json(&serde_json::json!({"status": "healthy"}))
});
// Bind to all interfaces in production
app.listen("0.0.0.0:8080").await
}
Source§impl App
Pre-configured application constructors for common scenarios.
impl App
Pre-configured application constructors for common scenarios.
These methods provide sensible defaults for different types of applications, saving you from having to manually configure common middleware combinations.
Sourcepub fn with_logging() -> Self
pub fn with_logging() -> Self
Creates a new app with request logging middleware enabled.
This is useful for development and debugging, as it logs all incoming requests with their method, path, and response status.
§Examples
use torch_web::{App, Request, Response};
let app = App::with_logging()
.get("/", |_req: Request| async {
Response::ok().body("Hello, World!")
});
Sourcepub fn with_cors() -> Self
pub fn with_cors() -> Self
Creates a new app with CORS (Cross-Origin Resource Sharing) middleware enabled.
This allows your API to be accessed from web browsers running on different domains. Useful for frontend applications that need to call your API.
§Examples
use torch_web::{App, Request, Response};
let app = App::with_cors()
.get("/api/data", |_req: Request| async {
Response::ok().json(&serde_json::json!({"data": "value"}))
});
Sourcepub fn with_defaults() -> Self
pub fn with_defaults() -> Self
Creates a production-ready app with comprehensive middleware stack.
This includes:
- Request logging and monitoring
- Performance metrics collection
- Security headers (HSTS, CSP, etc.)
- Request ID generation
- Input validation
- CORS support
- Request timeout (30 seconds)
- Request size limit (16MB)
- Health check endpoint
§Examples
use torch_web::{App, Request, Response};
let app = App::with_defaults()
.get("/", |_req: Request| async {
Response::ok().body("Production app")
})
.get("/api/users", |_req: Request| async {
Response::ok().json(&serde_json::json!({"users": []}))
});
Sourcepub fn with_security() -> Self
pub fn with_security() -> Self
Creates an app with essential security middleware enabled.
This includes:
- Security headers (HSTS, CSP, X-Frame-Options, etc.)
- Request ID generation for tracking
- Input validation to prevent common attacks
§Examples
use torch_web::{App, Request, Response};
let app = App::with_security()
.get("/secure-endpoint", |_req: Request| async {
Response::ok().body("This endpoint has security headers")
});
Sourcepub fn with_monitoring() -> Self
pub fn with_monitoring() -> Self
Creates an app with monitoring and metrics collection enabled.
This includes:
- Request logging
- Performance metrics collection
- Performance monitoring
- Health check endpoint at
/health
§Examples
use torch_web::{App, Request, Response};
let app = App::with_monitoring()
.get("/api/status", |_req: Request| async {
Response::ok().json(&serde_json::json!({"status": "ok"}))
});