| Crates.io | lmrc-http-common |
| lib.rs | lmrc-http-common |
| version | 0.3.16 |
| created_at | 2025-11-30 15:53:29.874656+00 |
| updated_at | 2025-12-11 13:28:11.302709+00 |
| description | Common HTTP utilities and patterns for LMRC Stack applications |
| homepage | |
| repository | https://gitlab.com/lemarco/lmrc-stack |
| max_upload_size | |
| id | 1958407 |
| size | 130,157 |
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.
validator crateAdd to your Cargo.toml:
[dependencies]
lmrc-http-common = "0.3.11"
auth (default) - Authentication utilities (JWT, bcrypt, sessions)validation (default) - Request validation helpersserver - Server bootstrap utilities (requires tracing-subscriber, dotenvy)To enable all features:
[dependencies]
lmrc-http-common = { version = "0.3.11", features = ["server"] }
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)))
}
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(())
}
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);
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 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
}
errorStandard 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) → 500Use the app_error! macro to create custom error types:
use lmrc_http_common::app_error;
app_error! {
MyAppError {
BusinessLogic(String),
ExternalApi(String),
}
}
responseStandard response wrappers:
SuccessResponse<T> - Standard success response with dataCreatedResponse<T> - 201 Created with location headerEmptyResponse - 204 No ContentPaginatedResponse<T> - Paginated list with metadatamiddlewareReusable 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 originsconfigConfiguration management:
ServerConfig - Host, port, CORS originsDatabaseConfig - Database URL, connection pool settingsConfigLoader trait - For custom configuration typeshealthHealth check framework:
HealthStatus - Overall application healthHealthCheck trait - Implement for custom checksHealthChecker - Aggregates multiple health checkshealth_handler - Axum handler for health endpointauth (requires auth feature)Authentication utilities:
jwt - JWT token creation and verificationpassword - Password hashing and verification (bcrypt)session - Session managementextractors (requires validation feature)Auto-validating request extractors:
ValidatedJson<T> - JSON with automatic validationValidatedQuery<T> - Query parameters with validationserver (requires server feature)Server bootstrap utilities:
ServerBootstrap - Fluent API for server setupquick_start - Simple one-liner server startSee the examples directory for complete working examples:
gateway - API gateway with routing and authapi-service-template - Standard REST API templateinfra-api - Infrastructure management APIcargo test -p lmrc-http-common --all-features
cargo doc --open -p lmrc-http-common --all-features
Dual licensed under MIT OR Apache-2.0 (your choice).
This library is part of the LMRC Stack monorepo.
See the main repository for contribution guidelines.