Skip to content

hnlearndev/blog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

45 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Willian Nguyen's blog

Status

The final product is williannguyen.com.

Full personal reflection on this project can be found on this post.

Note:

There is a regular status service to check that the website should work. This is one of the feature can be seen in the source code. If it does not (mismatch with status), please dm me. Thank you for your helps.

ARCHITECTURE OVERVIEW

This application follows a full-stack Rust architecture using:

  • Frontend: Leptos with hydration for interactive client-side features
  • Backend: Axum web framework with PostgreSQL database
  • Rendering: Server-side rendering (SSR) with client-side hydration
  • Content: Markdown-based blog posts with syntax highlighting
  • Build System: Custom build script for static content generation

TECH STACK

Core Framework

Database & ORM

  • PostgreSQL - Primary database
  • SQLx 0.8 - Async SQL toolkit with compile-time checked queries
  • Database Migrations - Version-controlled schema management

Content Processing

  • pulldown-cmark - Markdown parser
  • syntect - Syntax highlighting for code blocks
  • Static Content Generation - Build-time markdown processing

Development & Deployment

  • cargo-leptos - Leptos build tool
  • Hot Reload - Development server with live reloading
  • WASM Optimization - Size-optimized WebAssembly builds
  • End-to-End Testing - Playwright integration

PROJECT STRUCTURE

🌐 Frontend (Leptos)

The implementation is obtained from cargo-leptos axum template. For more detail, please follow the the instruction.

src/
β”œβ”€β”€ app.rs                 # App component and routing
β”œβ”€β”€ client.rs              # Client-side hydration entry
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ helpers.rs         # UI utility functions
β”‚   β”œβ”€β”€ components.rs      # Component module definitions
β”‚   β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ pages.rs
β”‚   └── pages/             # Page module definitions

βš™οΈ Backend (Axum) Architecture

The backend structure seen below is over-engineered for the purpose of personal blog with only public newsletter subcriber feature.

However, the industry-graded architecture is purposely used to study fullstack technology with Rust. The architecture is learnt from the book FullStack Rust with Axum from Martin Fabio

β”œβ”€β”€ main.rs                 # Application entry point
β”œβ”€β”€ server.rs               # Server orchestration & middleware stack
└── server/                 # Modular backend architecture
    β”œβ”€β”€ db.rs               # Database module coordinator
    β”œβ”€β”€ db/
    β”‚   β”œβ”€β”€ config.rs       # Database URL & connection config
    β”‚   β”œβ”€β”€ pool.rs         # PgPool initialization & management
    β”‚   β”œβ”€β”€ state.rs        # AppState with shared resources
    β”‚   └── error.rs        # Database-specific error handling
    β”œβ”€β”€ middleware.rs       # Middleware module coordinator
    β”œβ”€β”€ middleware/
    β”‚   β”œβ”€β”€ cache.rs        # HTTP caching strategies
    β”‚   β”œβ”€β”€ governor.rs     # Rate limiting (IP-based)
    β”‚   β”œβ”€β”€ csrf.rs         # CSRF token protection
    β”‚   β”œβ”€β”€ throttle.rs     # Request throttling
    β”‚   β”œβ”€β”€ global_layer.rs # Middleware layer coordinator
    β”‚   └── global_layer/
    β”‚       β”œβ”€β”€ cors.rs                 # Cross-Origin Resource Sharing
    β”‚       └── security_headers.rs     # Security headers middleware
    β”œβ”€β”€ models.rs           # Data model coordinator
    β”œβ”€β”€ models/
    β”‚   β”œβ”€β”€ subscriber.rs   # Newsletter subscriber model
    β”‚   └── status.rs       # Status badge model (for shields.io)
    β”œβ”€β”€ repositories.rs     # Data access coordinator
    β”œβ”€β”€ repositories/
    β”‚   β”œβ”€β”€ subscriber.rs   # Database queries & data access
    β”‚   └── status.rs       # Status badge logic (checks and aggregates status)
    β”œβ”€β”€ services.rs         # Business logic coordinator
    β”œβ”€β”€ services/
    β”‚   β”œβ”€β”€ subscriber.rs   # Newsletter business logic
    β”‚   └── status.rs       # Status badge update logic (periodic background updater)
    β”œβ”€β”€ handlers.rs         # Request handler coordinator
    β”œβ”€β”€ handlers/
    β”‚   β”œβ”€β”€ subscriber.rs   # HTTP request/response handling
    β”‚   └── status.rs       # Status badge API handler (serves cached status)
    β”œβ”€β”€ routes.rs           # API route coordinator
    └── routes/
        β”œβ”€β”€ subscriber.rs   # Newsletter API endpoints
        └── status.rs       # Status badge AP endpoint (`/status-badge` for shields.io)

🏘️ Backend Layer Relationships

graph TD
  Middleware["🧩 Middleware Stack<br/>(server.rs & routes/)"]
  Middleware -->|Applied globally and per route| Routes["πŸ›£οΈ Routes"]
  Routes -->|Use| Handlers["πŸ‘ Handlers"]
  Handlers -->|Use| Services["πŸ›ŽοΈ Services"]
  Services -->|Use| Repositories["πŸ“¦ Repositories"]
  Repositories -->|Use| Models["πŸ“„ Models"]
  Repositories -->|Use| DB["πŸ—„οΈ DB"]
Loading

Middleware & Security Features

  • Global
    • Compression: Brotli compression for responses
    • Request Timeout: Configurable request timeouts
    • Security Headers: Comprehensive HTTP security headers
  • Route specific
    • Rate Limiting: Per-IP request throttling using Governor
    • CORS: Cross-Origin Resource Sharing configuration
    • CSRF Protection: Token-based CSRF mitigation

Layer Responsibilities

  • Routes: HTTP endpoints + middleware application, delegate to handlers
  • Handlers: HTTP request/response processing, input validation
  • Services: Business logic, orchestration, transaction management
  • Repositories: Data access queries, DB operations using models
  • Models: Data structures, serialization, validation rules
  • DB: Connection pooling, configuration, state management

BUILD SYSTEM

The project uses a custom build script (build.rs) that:

  1. Processes Markdown Files: Reads blog posts from contents/posts/
  2. Syntax Highlighting: Applies code highlighting using Syntect
  3. Static Generation: Converts markdown to HTML at build time
  4. Optimized Output: Generates Rust code with static post data

PERFORMANCE FEATURES

  • Server-Side Rendering (SSR): Fast initial page loads
  • Hydration: Interactive client-side features without full SPA overhead
  • Static Content: Build-time markdown processing reduces runtime overhead
  • Compression: Brotli compression for smaller payload sizes
  • Connection Pooling: Efficient database connection management
  • Request Timeout: Prevents long-running requests from blocking resources
  • HTTP Caching Strategy: Multi-tier caching system for optimal performance
  • WASM Optimization: Aggressive size optimization for client-side bundles

WASM BUNDLE OPTIMIZATION

The WebAssembly build process includes several standard optimization techniques to minimize bundle size:

Optimization Techniques

  • Size-focused compilation (opt-level = 'z')
  • Link-time optimization (LTO)
  • Strip debug symbols (strip = true)
  • Abort on panic (panic = "abort")
  • Single codegen unit
  • Use wee_alloc for smaller WASM allocator

Benchmark Results

Below information is obtained from the actual implementation on the project and get benchmark to show the efficency of these technuques.

Metric Before Optimization After Optimization Improvement
Bundle Size 8.5MB 1.5MB 82.4% smaller
Gzipped Size ~2.1MB ~400-600KB ~75% smaller
Load Time Impact Baseline Significantly improved 5.6x smaller

Impact

  • Faster page loads: 82% smaller WASM bundles load much faster
  • Reduced bandwidth: Significant savings in data transfer
  • Better mobile experience: Smaller bundles improve performance on slower connections
  • Production ready: Size is now within reasonable limits for web deployment

CACHING

Deploy standard industry practices

  • Static Assets:
    • Uses Cache-Control: public, max-age=31536000 for 1-year caching.
    • Assets are versioned for cache busting, ensuring users get updates when files change.
  • API Responses:
    • Uses Cache-Control: public, max-age=60 for short-term caching (1 minute).
    • Improves performance for read-only endpoints and reduces database load.
  • Sensitive/Dynamic Endpoints:
    • Uses Cache-Control: no-store to prevent caching of user actions and sensitive data.

Future Features

  • Centralized Error Handling (Status: Planned)

To add a middleware layer to catch errors, log them, and provide consistent user-friendly responses. Implementation is postponed until the app grows in complexity.

  • Modulized global layer (Status: Planned)

This was planned out at the begginning with tower crate 's ServiceBuilder as a global layer which is then called into server.rs. However, refactoring this seperated out from server.rs run is more troublesome than expected. Until the project expands further, it is placed directly in server.rs.

Reference

About

Personal blog written in Rust Leptos and Axum

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

  •  

Packages

No packages published