15 releases
Uses new Rust 2024
| 0.3.16 | Dec 11, 2025 |
|---|---|
| 0.3.15 | Dec 11, 2025 |
| 0.3.9 | Nov 30, 2025 |
#860 in HTTP server
Used in 2 crates
82KB
1.5K
SLoC
lmrc-http-common
Common HTTP utilities and patterns for LMRC Stack applications.
This library provides reusable components for building Axum-based HTTP services with best practices built-in.
Features
- Error Handling: Standard HTTP error types with automatic response conversion
- Response Wrappers: Success, created, empty, and paginated response types
- Middleware: CORS, logging, request ID, and more
- Authentication (optional): JWT, password hashing, session management
- Configuration Management: Server and database configuration loading
- Health Checks: Standardized health check framework
- Validated Extractors (optional): Auto-validate requests with
validatorcrate - Server Bootstrap (optional): Quick server setup with tracing and configuration
Installation
Add to your Cargo.toml:
[dependencies]
lmrc-http-common = "0.3.11"
Feature Flags
auth(default) - Authentication utilities (JWT, bcrypt, sessions)validation(default) - Request validation helpersserver- Server bootstrap utilities (requirestracing-subscriber,dotenvy)
To enable all features:
[dependencies]
lmrc-http-common = { version = "0.3.11", features = ["server"] }
Quick Start
Basic Handler with Error Handling
use lmrc_http_common::{
error::{HttpError, HttpResult},
response::SuccessResponse,
};
use axum::{Router, routing::get, Json};
async fn get_user(id: u32) -> HttpResult<Json<SuccessResponse<User>>> {
let user = database
.find_user(id)
.await
.ok_or_else(|| HttpError::NotFound(format!("User {} not found", id)))?;
Ok(Json(SuccessResponse::new(user)))
}
Configuration Loading
use lmrc_http_common::config::{ServerConfig, DatabaseConfig};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Load configuration from environment variables
let server_config = ServerConfig::from_env()?;
let db_config = DatabaseConfig::from_env(None)?;
println!("Starting server on {}", server_config.bind_addr()?);
Ok(())
}
Health Checks
use lmrc_http_common::health::{HealthChecker, HealthCheck, CheckResult};
use std::sync::Arc;
use async_trait::async_trait;
struct DatabaseHealthCheck {
db: DatabaseConnection,
}
#[async_trait]
impl HealthCheck for DatabaseHealthCheck {
async fn check(&self) -> CheckResult {
match self.db.ping().await {
Ok(_) => CheckResult::healthy_with_message("Database connected"),
Err(e) => CheckResult::unhealthy(format!("Database error: {}", e)),
}
}
fn name(&self) -> &str {
"database"
}
}
// In your router setup:
let checker = Arc::new(
HealthChecker::new(env!("CARGO_PKG_VERSION"))
.add_check(Arc::new(DatabaseHealthCheck { db }))
);
let app = Router::new()
.route("/health", get(lmrc_http_common::health::health_handler))
.with_state(checker);
Validated Request Extractors
use lmrc_http_common::extractors::ValidatedJson;
use serde::Deserialize;
use validator::Validate;
#[derive(Deserialize, Validate)]
struct CreateUser {
#[validate(length(min = 3, max = 50))]
username: String,
#[validate(email)]
email: String,
}
async fn create_user(
ValidatedJson(payload): ValidatedJson<CreateUser>
) -> &'static str {
// payload is automatically validated!
// Returns 422 Unprocessable Entity if validation fails
"User created"
}
Server Bootstrap (with server feature)
use axum::{Router, routing::get};
use lmrc_http_common::server::ServerBootstrap;
#[derive(Clone)]
struct AppState {
config: Config,
db: DatabaseConnection,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let state = AppState {
config: Config::from_env()?,
db: DatabaseConnection::new().await?,
};
ServerBootstrap::with_state(state)
.with_tracing("myapp")
.with_port(8080)
.with_router(|state| {
Router::new()
.route("/health", get(|| async { "OK" }))
.with_state(state)
})
.serve()
.await
}
Or use the quick start helper:
use axum::{Router, routing::get};
use lmrc_http_common::server::quick_start;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let router = Router::new().route("/health", get(|| async { "OK" }));
quick_start("myapp", router, 8080).await
}
Module Overview
error
Standard HTTP error types that automatically convert to appropriate HTTP responses:
HttpError::BadRequest(String)→ 400HttpError::Unauthorized(String)→ 401HttpError::Forbidden(String)→ 403HttpError::NotFound(String)→ 404HttpError::ValidationError(String)→ 422HttpError::InternalServer(String)→ 500
Use the app_error! macro to create custom error types:
use lmrc_http_common::app_error;
app_error! {
MyAppError {
BusinessLogic(String),
ExternalApi(String),
}
}
response
Standard response wrappers:
SuccessResponse<T>- Standard success response with dataCreatedResponse<T>- 201 Created with location headerEmptyResponse- 204 No ContentPaginatedResponse<T>- Paginated list with metadata
middleware
Reusable middleware layers:
add_request_id- Adds unique request ID to each requestlog_request- Logs all requests with durationcors_with_origins(Vec<String>)- CORS with specific origins
config
Configuration management:
ServerConfig- Host, port, CORS originsDatabaseConfig- Database URL, connection pool settingsConfigLoadertrait - For custom configuration types
health
Health check framework:
HealthStatus- Overall application healthHealthChecktrait - Implement for custom checksHealthChecker- Aggregates multiple health checkshealth_handler- Axum handler for health endpoint
auth (requires auth feature)
Authentication utilities:
jwt- JWT token creation and verificationpassword- Password hashing and verification (bcrypt)session- Session management
extractors (requires validation feature)
Auto-validating request extractors:
ValidatedJson<T>- JSON with automatic validationValidatedQuery<T>- Query parameters with validation
server (requires server feature)
Server bootstrap utilities:
ServerBootstrap- Fluent API for server setupquick_start- Simple one-liner server start
Examples
See the examples directory for complete working examples:
gateway- API gateway with routing and authapi-service-template- Standard REST API templateinfra-api- Infrastructure management API
Development
Running Tests
cargo test -p lmrc-http-common --all-features
Building Documentation
cargo doc --open -p lmrc-http-common --all-features
License
Dual licensed under MIT OR Apache-2.0 (your choice).
Contributing
This library is part of the LMRC Stack monorepo.
See the main repository for contribution guidelines.
Dependencies
~10–28MB
~312K SLoC