Skip to content

A comprehensive Rust web API foundation library providing reusable patterns and utilities for building consistent, maintainable web APIs

Notifications You must be signed in to change notification settings

AvinasiLabs/avinapi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Avinapi

A comprehensive Rust web API foundation library providing reusable patterns and utilities for building consistent, maintainable web APIs.

Rust License Tests

πŸš€ Features

πŸ“‹ Query Parameters

  • DateRangeQuery - Simple date-based filtering (YYYY-MM-DD format)
  • DateTimeRangeQuery - Precise datetime filtering with timezone support (RFC 3339)
  • PaginationQuery - Page-based pagination with metadata
  • SortQuery - Flexible multi-field sorting with SQL generation

πŸ”„ Response Handling

  • ApiResponse<T> - Standardized JSON response format
  • PaginatedData<T> - Paginated response wrapper with metadata
  • Response macros - data!(), empty!() for quick responses

❌ Error Management

  • AppError - Comprehensive error types for web applications
  • Unified HTTP 200 responses - All responses return HTTP 200 with business codes in JSON
  • Business code mapping - Errors map to semantic business codes (SUCCESS, VALIDATION_ERROR, etc.)
  • Validation integration - Seamless validator crate integration

βœ… Validation

  • ValidatedJson<T> - JSON extractor with automatic validation
  • Custom validators - Password strength, phone numbers, email, etc.
  • Query validation - Built-in validation for all query parameter types

πŸ› οΈ Utilities

  • Middleware helpers - CORS, request ID, tracing integration
  • OpenAPI support - Full utoipa integration with examples
  • Feature flags - Optional dependencies (axum, sqlx, jwt)

πŸ“¦ Installation

Add this to your Cargo.toml:

[dependencies]
avinapi = "0.1.0"

# Optional features
avinapi = { version = "0.1.0", features = ["axum", "sqlx", "jwt"] }

Available Features

  • axum (default) - Axum web framework integration
  • sqlx (default) - Database integration utilities
  • jwt (default) - JWT authentication helpers

🎯 Quick Start

use avinapi::prelude::*;
use axum::{Router, extract::Query, routing::get};

#[derive(serde::Serialize)]
struct User {
    id: u32,
    name: String,
    email: String,
}

// Simple pagination endpoint
async fn list_users(
    Query(pagination): Query<PaginationQuery>,
) -> JsonResult<PaginatedData<User>> {
    let users = get_users_from_db(
        pagination.get_limit(),
        pagination.get_offset(),
    ).await?;
    
    let total_count = count_users().await?;
    let response = PaginatedData::new(users, &pagination, total_count);
    
    data!(response)
}

// Advanced filtering with multiple query parameters
async fn list_orders(
    Query(pagination): Query<PaginationQuery>,
    Query(date_range): Query<DateTimeRangeQuery>,
    Query(sort): Query<SortQuery>,
) -> JsonResult<PaginatedData<Order>> {
    // Validate datetime range (max 30 days)
    date_range.validate_max_duration(30)?;
    
    // Parse to UTC for database queries
    let start_utc = date_range.parse_start_utc()?;
    let end_utc = date_range.parse_end_utc()?;
    
    // Generate SQL ORDER BY clause
    let order_clause = sort.to_sql_with_prefix("orders");
    
    let orders = query_orders(start_utc, end_utc, order_clause, pagination).await?;
    data!(orders)
}

fn main() {
    let app = Router::new()
        .route("/users", get(list_users))
        .route("/orders", get(list_orders));
    
    // ... run server
}

πŸ—“οΈ Date Handling Examples

Simple Date Filtering

// URL: /reports?start_date=2024-01-01&end_date=2024-12-31
async fn reports(Query(date_range): Query<DateRangeQuery>) -> JsonResult<Vec<Report>> {
    let reports = Report::find_by_date_range(
        date_range.start_date,
        date_range.end_date
    ).await?;
    
    data!(reports)
}

Precise DateTime Filtering with Timezones

// URL: /events?start_datetime=2024-12-19T10:30:00+08:00&end_datetime=2024-12-19T18:00:00+08:00
async fn events(Query(datetime_range): Query<DateTimeRangeQuery>) -> JsonResult<Vec<Event>> {
    // Validate range
    datetime_range.validate_range()?;
    datetime_range.validate_max_duration(7)?; // Max 7 days
    
    // Parse to UTC (handles timezone conversion automatically)
    let start_utc = datetime_range.parse_start_utc()?;
    let end_utc = datetime_range.parse_end_utc()?;
    
    let events = Event::find_by_datetime_range(start_utc, end_utc).await?;
    data!(events)
}

πŸ“Š Supported Date Formats

DateRangeQuery (Simple dates)

  • start_date=2024-12-19 - Date only format
  • end_date=2024-12-31 - Perfect for daily/monthly reports

DateTimeRangeQuery (Precise times)

  • start_datetime=2024-12-19T10:30:00Z - UTC format
  • start_datetime=2024-12-19T10:30:00+08:00 - Timezone aware
  • start_datetime=2024-12-19T10:30:00-05:00 - Negative timezone

βœ… Validation Example

use avinapi::{ValidatedJson, validation::*};

#[derive(Deserialize, Validate, ToSchema)]
struct CreateUserRequest {
    #[validate(length(min = 1, max = 100))]
    name: String,
    
    #[validate(email)]
    email: String,
    
    #[validate(custom = "validate_password_strength")]
    password: String,
}

async fn create_user(
    ValidatedJson(request): ValidatedJson<CreateUserRequest>
) -> JsonResult<User> {
    // Request is guaranteed to be valid here
    let user = User::create(request.name, request.email, request.password).await?;
    data!(user)
}

🎨 Response Format

Important: This library follows a unified response pattern where all endpoints return HTTP 200 status codes, with business logic status indicated by the code field in the JSON response body.

All endpoints return a consistent JSON structure:

{
  "code": "SUCCESS",           // Business status code
  "data": { ... },            // Response data
  "message": null             // Optional message
}

Error responses (still HTTP 200):

{
  "code": "VALIDATION_ERROR", // Business error code
  "data": null,
  "message": "name: Name is required, email: Invalid email format"
}

Supported Business Codes

  • SUCCESS - Operation completed successfully
  • VALIDATION_ERROR - Input validation failed
  • AUTHENTICATION_ERROR - Authentication required or failed
  • AUTHORIZATION_ERROR - Insufficient permissions
  • NOT_FOUND - Requested resource not found
  • CONFLICT - Resource conflict (e.g., duplicate email)
  • INTERNAL_ERROR - Server-side error
  • DATABASE_ERROR - Database operation failed
  • NETWORK_ERROR - External service call failed

Paginated responses:

{
  "code": "SUCCESS",
  "data": {
    "data": [...],
    "meta": {
      "current_page": 1,
      "per_page": 20,
      "total_items": 150,
      "total_pages": 8,
      "has_next_page": true,
      "has_prev_page": false
    }
  },
  "message": null
}

πŸ”§ Configuration

Cargo.toml features

# Minimal setup
avinapi = { version = "0.1.0", default-features = false }

# With specific features
avinapi = { version = "0.1.0", features = ["axum", "sqlx"] }

# Full features
avinapi = { version = "0.1.0", features = ["axum", "sqlx", "jwt"] }

Environment variables

The library respects these environment variables:

  • RUST_LOG - Logging level (uses tracing)
  • DATABASE_URL - Database connection (when using sqlx feature)

πŸ—οΈ Architecture

avinapi/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ error/          # Error handling and HTTP status mapping
β”‚   β”œβ”€β”€ middleware/     # Common middleware utilities
β”‚   β”œβ”€β”€ query/          # Query parameter types and validation
β”‚   β”‚   β”œβ”€β”€ date_range.rs      # Simple date filtering
β”‚   β”‚   β”œβ”€β”€ datetime_range.rs  # Precise datetime filtering
β”‚   β”‚   β”œβ”€β”€ pagination.rs     # Page-based pagination
β”‚   β”‚   └── sort.rs           # Multi-field sorting
β”‚   β”œβ”€β”€ response/       # Standardized response types
β”‚   β”œβ”€β”€ validation/     # JSON validation and custom validators
β”‚   └── prelude.rs     # Common imports
β”œβ”€β”€ examples/          # Usage examples
└── tests/            # Integration tests

πŸ“š Examples

Run the included examples:

# Basic query parameter usage
cargo run --example query_parameters

# DateTime range handling with different formats
cargo run --example datetime_range_usage

Then visit:

  • http://localhost:3000/users?page=1&per_page=10
  • http://localhost:3000/calendar?start_datetime=2024-12-19T10:30:00+08:00

🀝 Integration with Other Crates

Axum Integration

use avinapi::prelude::*;
use axum::{Router, middleware};

let app = Router::new()
    .route("/api/users", get(list_users))
    .layer(middleware::from_fn(request_id_middleware))
    .layer(cors_layer());

SQLx Integration

use avinapi::query::*;
use sqlx::{PgPool, query_as};

async fn get_orders(
    pool: &PgPool,
    datetime_range: &DateTimeRangeQuery,
    pagination: &PaginationQuery,
) -> Result<Vec<Order>, sqlx::Error> {
    let (start_utc, end_utc) = datetime_range.parse_utc_range();
    
    query_as!(
        Order,
        r#"
        SELECT * FROM orders 
        WHERE ($1::timestamptz IS NULL OR created_at >= $1)
          AND ($2::timestamptz IS NULL OR created_at < $2)
        ORDER BY created_at DESC
        LIMIT $3 OFFSET $4
        "#,
        start_utc,
        end_utc,
        pagination.get_limit() as i64,
        pagination.get_offset() as i64
    )
    .fetch_all(pool)
    .await
}

πŸ§ͺ Testing

# Run all tests
cargo test

# Run with all features
cargo test --all-features

# Run examples
cargo test --examples

# Run doc tests
cargo test --doc

πŸ“– Documentation

πŸ”„ Versioning

This project follows Semantic Versioning:

  • MAJOR version for incompatible API changes
  • MINOR version for backwards-compatible functionality additions
  • PATCH version for backwards-compatible bug fixes

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Development setup

git clone https://github.com/AvinasiLabs/avinapi
cd avinapi
cargo build --all-features
cargo test --all-features

πŸ“„ License

This project is licensed under either of

at your option.

πŸ™ Acknowledgments

  • Axum - Modern web framework
  • Chrono - Date and time library
  • Serde - Serialization framework
  • Validator - Data validation
  • utoipa - OpenAPI documentation

πŸ‘¨β€πŸ’» Author

Created by @lilhammer111 | Latte Team, Avinasi Labs

About

A comprehensive Rust web API foundation library providing reusable patterns and utilities for building consistent, maintainable web APIs

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages