| Crates.io | arche |
| lib.rs | arche |
| version | 0.1.1 |
| created_at | 2026-01-23 13:08:21.561371+00 |
| updated_at | 2026-01-23 13:08:21.561371+00 |
| description | An opinionated backend foundation for Axum applications, providing batteries-included integrations for cloud services, databases, authentication, middleware, and logging. |
| homepage | https://github.com/sinha-sahil/arche |
| repository | https://github.com/sinha-sahil/arche |
| max_upload_size | |
| id | 2064446 |
| size | 144,018 |
arche is an opinionated backend foundation crate for building production-ready applications with Axum.
It provides a curated set of building blocks commonly required in modern backend services—cloud integrations, databases, authentication, middleware, and logging— so you can focus on business logic instead of repetitive infrastructure wiring.
arche is designed to sit around Axum, not replace it.
Most backend services end up re-implementing the same infrastructure concerns:
arche brings these pieces together into a cohesive, Rust-native foundation, built on top of well-established libraries and SDKs.
awsAWS SDK integrations built on official SDKs:
gcpGoogle Cloud Platform integrations:
databaseDatabase connection management:
sqlx, configurable credentials, health checksbb8, async operations, health checksjwtJWT utilities for authentication and authorization:
errorAxum-compatible error handling:
AppError enum with common HTTP error variantsIntoResponse conversionutilsCommon utilities for backend services:
OffsetDateTime utilities (Unix, ISO8601)All components are modular and explicit—nothing is hidden or magical.
arche::aws)Initialize an S3 client with automatic credential management:
use arche::aws::s3::get_s3_client;
let client = get_s3_client().await;
Environment Variables:
S3_CRED_SOURCE: "IAM" (default) or "env" for environment-based credentialsS3_ACCESS_KEY_ID: Required when using "env" credential sourceS3_SECRET_ACCESS_KEY: Required when using "env" credential sourcearche::gcp)use arche::gcp::drive::get_drive_client;
let drive = get_drive_client().await?;
Environment Variables:
GCP_DRIVE_KEY: Path to service account JSON key fileuse arche::gcp::sheets::get_sheets_client;
let sheets = get_sheets_client().await?;
Environment Variables:
GCP_SHEETS_KEY: Path to service account JSON key filearche::database)use arche::database::pg::{get_pg_pool, test_pg};
let pool = get_pg_pool().await;
let is_healthy = test_pg(pool.clone()).await;
Environment Variables:
PG_HOST: Database hostPG_PORT: Database portPG_DATABASE: Database namePG_MAX_CONN: Maximum connections in poolPG_CREDENTIALS: JSON string with username and password (alternative)PG_USERNAME: Username (if not using PG_CREDENTIALS)PG_PASSWORD: Password (if not using PG_CREDENTIALS)use arche::database::redis::{get_redis_pool, test_redis};
let pool = get_redis_pool().await;
let is_healthy = test_redis(pool.clone()).await;
Environment Variables:
REDIS_HOST: Redis hostREDIS_PORT: Redis portREDIS_MAX_CONN: Maximum connections in poolarche::jwt)use arche::jwt::{generate_tokens, verify_token, generate_expiry_time};
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct Claims {
sub: String,
exp: usize,
}
// Generate tokens
let access_claims = Claims { sub: "user_id".into(), exp: generate_expiry_time(3600) };
let refresh_claims = Claims { sub: "user_id".into(), exp: generate_expiry_time(86400) };
let tokens = generate_tokens(
access_claims,
refresh_claims,
&access_secret,
&refresh_secret,
);
// Verify token
let token_data = verify_token::<Claims>(&token, secret, Some("audience".into()))?;
arche::error)use arche::error::AppError;
use axum::response::IntoResponse;
async fn handler() -> Result<impl IntoResponse, AppError> {
Err(AppError::Unauthorized)
}
// Custom errors with details
let error = AppError::bad_request(
Some(errors_map),
Some("Invalid input".into()),
Some("Field validation failed".into()),
);
Error Variants:
Unauthorized → 401BadRequest → 400UnprocessableEntity → 422DBError → 500InternalError → 500Unavailable → 503arche::utils)use arche::utils::{validate_timestamp, FromOffsetDateTime, PaginationParams};
use sqlx::types::time::OffsetDateTime;
// Timestamp validation
let is_future = validate_timestamp(timestamp, false);
// DateTime conversion
let iso_string = offset_dt.to_iso_string()?;
// Pagination
let params = PaginationParams {
page_number: Some(1),
page_size: Some(20),
};
arche favors composition over abstraction.
Most backend services end up re-implementing the same infrastructure concerns:
arche brings these pieces together into a cohesive, Rust-native foundation, built on top of well-established libraries and SDKs.
awsAWS SDK integrations built on official SDKs:
gcpGoogle Cloud Platform integrations:
databaseDatabase connection management:
sqlx, configurable credentials, health checksbb8, async operations, health checksjwtJWT utilities for authentication and authorization:
errorAxum-compatible error handling:
AppError enum with common HTTP error variantsIntoResponse conversionutilsCommon utilities for backend services:
OffsetDateTime utilities (Unix, ISO8601)All components are modular and explicit—nothing is hidden or magical.
arche::aws)Initialize an S3 client with automatic credential management:
use arche::aws::s3::get_s3_client;
let client = get_s3_client().await;
Environment Variables:
S3_CRED_SOURCE: "IAM" (default) or "env" for environment-based credentialsS3_ACCESS_KEY_ID: Required when using "env" credential sourceS3_SECRET_ACCESS_KEY: Required when using "env" credential sourcearche::gcp)use arche::gcp::drive::get_drive_client;
let drive = get_drive_client().await?;
Environment Variables:
GCP_DRIVE_KEY: Path to service account JSON key fileuse arche::gcp::sheets::get_sheets_client;
let sheets = get_sheets_client().await?;
Environment Variables:
GCP_SHEETS_KEY: Path to service account JSON key filearche::database)use arche::database::pg::{get_pg_pool, test_pg};
let pool = get_pg_pool().await;
let is_healthy = test_pg(pool.clone()).await;
Environment Variables:
PG_HOST: Database hostPG_PORT: Database portPG_DATABASE: Database namePG_MAX_CONN: Maximum connections in poolPG_CREDENTIALS: JSON string with username and password (alternative)PG_USERNAME: Username (if not using PG_CREDENTIALS)PG_PASSWORD: Password (if not using PG_CREDENTIALS)use arche::database::redis::{get_redis_pool, test_redis};
let pool = get_redis_pool().await;
let is_healthy = test_redis(pool.clone()).await;
Environment Variables:
REDIS_HOST: Redis hostREDIS_PORT: Redis portREDIS_MAX_CONN: Maximum connections in poolarche::jwt)use arche::jwt::{generate_tokens, verify_token, generate_expiry_time};
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct Claims {
sub: String,
exp: usize,
}
// Generate tokens
let access_claims = Claims { sub: "user_id".into(), exp: generate_expiry_time(3600) };
let refresh_claims = Claims { sub: "user_id".into(), exp: generate_expiry_time(86400) };
let tokens = generate_tokens(
access_claims,
refresh_claims,
&access_secret,
&refresh_secret,
);
// Verify token
let token_data = verify_token::<Claims>(&token, secret, Some("audience".into()))?;
arche::error)use arche::error::AppError;
use axum::response::IntoResponse;
async fn handler() -> Result<impl IntoResponse, AppError> {
Err(AppError::Unauthorized)
}
// Custom errors with details
let error = AppError::bad_request(
Some(errors_map),
Some("Invalid input".into()),
Some("Field validation failed".into()),
);
Error Variants:
Unauthorized → 401BadRequest → 400UnprocessableEntity → 422DBError → 500InternalError → 500Unavailable → 503arche::utils)use arche::utils::{validate_timestamp, FromOffsetDateTime, PaginationParams};
use sqlx::types::time::OffsetDateTime;
// Timestamp validation
let is_future = validate_timestamp(timestamp, false);
// DateTime conversion
let iso_string = offset_dt.to_iso_string()?;
// Pagination
let params = PaginationParams {
page_number: Some(1),
page_size: Some(20),
};
arche favors composition over abstraction.