Architecture
Understanding Azu's architecture is key to building effective applications. This guide covers the core architectural patterns, request lifecycle, and design principles that make Azu powerful and type-safe.
Core Architecture Principles
Type Safety First
Azu is built around Crystal's powerful type system, providing compile-time guarantees for:
Request Validation: All incoming data is validated at compile time
Response Structure: Response objects are type-safe and consistent
Route Parameters: URL parameters are typed and validated
WebSocket Messages: Real-time communication is type-safe
Component-Based Design
Azu follows a modular, component-based architecture:
Endpoints: Self-contained request handlers
Request Contracts: Type-safe input validation
Response Objects: Structured output handling
Channels: Real-time communication handlers
Components: Reusable UI components
Performance by Design
Built for high performance:
Compile-time Optimization: Crystal's compiler optimizes your code
Memory Efficiency: Predictable memory usage with no GC pauses
Concurrent Processing: Handle thousands of connections efficiently
Minimal Overhead: Framework adds minimal runtime cost
Request-Response Lifecycle
1. Request Processing
When a request arrives:
HTTP Server: Crystal's built-in HTTP server receives the request
Middleware Chain: Request passes through configured middleware
Router: Routes the request to the appropriate endpoint
Endpoint: Type-safe endpoint processes the request
2. Request Validation
struct UserRequest
include Azu::Request
@name : String
@email : String
validate name, presence: true, length: {min: 2, max: 50}
validate email, presence: true, format: /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
endRequest contracts automatically:
Parse and validate incoming data
Provide type-safe access to parameters
Generate detailed error messages
Ensure data integrity
3. Business Logic
struct UserEndpoint
include Azu::Endpoint(UserRequest, UserResponse)
post "/users"
def call : UserResponse
# Type-safe access to validated data
user = create_user(user_request.name, user_request.email)
UserResponse.new(user)
end
end4. Response Generation
struct UserResponse
include Azu::Response
def initialize(@user : User)
end
def render
{
id: @user.id,
name: @user.name,
email: @user.email,
created_at: @user.created_at.to_rfc3339
}.to_json
end
endMiddleware Architecture
Azu uses a middleware chain pattern for request processing:
Built-in Middleware
RequestId: Adds unique request identifiers
Logger: Request/response logging
CORS: Cross-origin resource sharing
Static: Static file serving
Rescuer: Error handling and recovery
Custom Middleware
class CustomMiddleware
include HTTP::Handler
def call(context : HTTP::Server::Context)
# Pre-processing
Log.info { "Processing request: #{context.request.path}" }
# Call next middleware
call_next(context)
# Post-processing
Log.info { "Request completed: #{context.response.status_code}" }
end
endRouting System
Azu uses a high-performance routing tree based on Radix:
router do
root :web, HomeEndpoint
routes :web, "/api" do
get "/users", ListUsersEndpoint
get "/users/:id", ShowUserEndpoint
post "/users", CreateUserEndpoint
put "/users/:id", UpdateUserEndpoint
delete "/users/:id", DeleteUserEndpoint
end
routes :web, "/admin" do
get "/dashboard", AdminDashboardEndpoint
end
endRoute Features
HTTP Methods: Support for all standard HTTP methods
Path Parameters: Typed URL parameters (
:id,:slug)Route Groups: Organize related routes
Nested Routes: Hierarchical route organization
Route Constraints: Additional validation rules
WebSocket Architecture
Real-time communication in Azu:
Channel Pattern
class NotificationChannel < Azu::Channel
CONNECTIONS = Set(HTTP::WebSocket).new
ws "/notifications"
def on_connect
CONNECTIONS << socket.not_nil!
send_welcome_message
end
def on_message(message : String)
handle_message(JSON.parse(message))
end
def on_close(code, message)
CONNECTIONS.delete(socket)
end
def self.broadcast_to_all(data)
CONNECTIONS.each { |socket| socket.send(data.to_json) }
end
endComponent System
Live components for interactive UI:
class CounterComponent
include Azu::Component
@count = 0
def content
div do
text "Count: #{@count}"
button "Increment", onclick: "increment"
end
end
def on_event("increment", data)
@count += 1
update!
end
endComponent Lifecycle
Mount: Component is created and registered
Render: Initial HTML is generated
Event Handling: Client events are processed
Update: Component state changes trigger re-renders
Unmount: Component is cleaned up
Template System
Azu includes a powerful template engine based on Jinja2:
Template Features
Variable Interpolation:
{{ variable }}Control Structures:
{% if %}loops and conditionalsTemplate Inheritance: Extend base templates
Hot Reload: Automatic template reloading in development
Markup DSL: Programmatic HTML generation
Template Rendering
struct UserPage
include Azu::Response
include Azu::Templates::Renderable
def initialize(@user : User)
end
def render
view "users/show.html", {
user: @user,
title: "User Profile"
}
end
endConfiguration System
Centralized configuration with environment support:
module MyApp
include Azu
configure do |config|
# Server configuration
config.host = "0.0.0.0"
config.port = 3000
config.env = "development"
# Template configuration
config.templates.path = ["templates"]
config.template_hot_reload = config.env.development?
# Upload configuration
config.upload.max_file_size = 10.megabytes
config.upload.temp_dir = "/tmp/uploads"
# Logging configuration
config.log.level = config.env.development? ? Log::Severity::DEBUG : Log::Severity::INFO
end
endError Handling
Comprehensive error handling system:
Error Types
ValidationError: Request validation failures
NotFound: Resource not found (404)
Unauthorized: Authentication failures (401)
Forbidden: Authorization failures (403)
InternalServerError: Server errors (500)
Error Response Format
{
"Status": "Unprocessable Entity",
"Title": "Validation Error",
"Detail": "The request could not be processed due to validation errors.",
"FieldErrors": {
"name": ["Name must be between 2 and 50 characters"],
"email": ["Email must be a valid email address"]
},
"ErrorId": "err_abc123",
"Fingerprint": "validation_error_abc",
"Timestamp": "2023-12-04T15:35:12Z"
}Performance Characteristics
Compile-time Optimizations
Type Elimination: Unused code is eliminated at compile time
Method Inlining: Small methods are inlined for performance
Dead Code Elimination: Unreachable code is removed
Constant Folding: Compile-time constant evaluation
Runtime Performance
Zero-cost Abstractions: Framework abstractions have minimal overhead
Memory Efficiency: Predictable memory usage patterns
Concurrent Processing: Efficient handling of multiple requests
Connection Pooling: Optimized database and external service connections
Benchmarking
Azu is designed for high performance:
Request Throughput: Handle thousands of requests per second
Memory Usage: Low memory footprint with predictable patterns
Latency: Sub-millisecond request processing overhead
Scalability: Efficient resource usage for horizontal scaling
Security Architecture
Built-in Security Features
CSRF Protection: Cross-site request forgery prevention
Input Validation: Comprehensive request validation
XSS Prevention: Automatic output escaping
SQL Injection Prevention: Type-safe database queries
Secure Headers: Security-focused HTTP headers
Security Best Practices
Input Sanitization: All user input is validated and sanitized
Output Encoding: Automatic HTML/XML encoding
Authentication: Secure session management
Authorization: Role-based access control
HTTPS Enforcement: Secure communication protocols
Development vs Production
Development Mode
Hot Reload: Automatic code and template reloading
Debug Logging: Detailed request/response logging
Error Pages: Comprehensive error information
Performance Monitoring: Development-time metrics
Production Mode
Optimized Compilation: Release-mode optimizations
Minimal Logging: Production-appropriate logging levels
Error Handling: User-friendly error responses
Performance Monitoring: Production metrics and alerting
Next Steps
Now that you understand Azu's architecture:
Endpoints - Learn about endpoint patterns and best practices
Request Contracts - Master request validation and type safety
Response Objects - Structure your API responses
Routing - Organize your application routes
Middleware - Customize request processing
WebSocket Channels - Build real-time features
Components - Create interactive UI components
Understanding Azu's architecture gives you the foundation to build robust, type-safe, and performant web applications with confidence.
Last updated
Was this helpful?
