Quick Start
This guide will walk you through creating your first Azu application in just a few minutes. By the end of this tutorial, you'll have a running web application with a database, complete with CRUD operations.
Prerequisites
Database server running (PostgreSQL, MySQL, or SQLite)
Basic familiarity with Crystal syntax
Step 1: Create a New Project
Let's create a blog application:
azu new my_blog --database postgres
This command will:
Create a new directory called
my_blog
Generate the complete project structure
Configure PostgreSQL as the database
Set up all necessary dependencies
Initialize a Git repository
Output:
π Creating new Azu project: my_blog
π¦ Using database: postgres
π Generating project structure...
create my_blog/
create my_blog/src/
create my_blog/src/my_blog.cr
create my_blog/src/server.cr
create my_blog/shard.yml
create my_blog/README.md
... (more files)
β
Project created successfully!
π Next Steps:
cd my_blog
azu db create
azu serve
Step 2: Navigate to Your Project
cd my_blog
Let's examine the generated project structure:
my_blog/
βββ src/
β βββ my_blog.cr # Main application file
β βββ server.cr # HTTP server configuration
β βββ endpoints/ # API endpoints (controllers)
β βββ models/ # Database models
β βββ contracts/ # Request/response contracts
β βββ pages/ # Page components (views)
β βββ services/ # Business logic services
β βββ middleware/ # HTTP middleware
β βββ initializers/ # Application initializers
βββ spec/ # Test files
βββ public/ # Static assets
βββ db/ # Database files
β βββ migrations/ # Database migrations
β βββ seed.cr # Database seeds
βββ shard.yml # Dependencies
βββ README.md # Project documentation
Step 3: Set Up the Database
Create your database:
azu db create
Output:
ποΈ Creating database: my_blog_development
β
Database created successfully!
Run initial migrations:
azu db migrate
Output:
π Running migrations...
β
All migrations completed successfully!
Step 4: Start the Development Server
Launch the development server with hot reloading:
azu serve
Output:
π Starting Azu development server...
π¦ Compiling application...
β
Compilation successful!
π Server running at: http://localhost:3000
π₯ Hot reloading enabled
π Watching for file changes...
Press Ctrl+C to stop the server
Open your browser and navigate to http://localhost:3000
. You should see the Azu welcome page!
Step 5: Generate Your First Resource
Let's create a complete blog post resource with CRUD operations:
azu generate scaffold Post title:string content:text published:boolean
Output:
π οΈ Generating scaffold: Post
create src/models/post.cr
create src/endpoints/posts/index_endpoint.cr
create src/endpoints/posts/show_endpoint.cr
create src/endpoints/posts/new_endpoint.cr
create src/endpoints/posts/create_endpoint.cr
create src/endpoints/posts/edit_endpoint.cr
create src/endpoints/posts/update_endpoint.cr
create src/endpoints/posts/destroy_endpoint.cr
create src/contracts/posts/index_contract.cr
create src/contracts/posts/show_contract.cr
create src/contracts/posts/create_contract.cr
create src/contracts/posts/update_contract.cr
create src/pages/posts/index_page.cr
create src/pages/posts/show_page.cr
create src/pages/posts/new_page.cr
create src/pages/posts/edit_page.cr
create public/templates/posts/index_page.jinja
create public/templates/posts/show_page.jinja
create public/templates/posts/new_page.jinja
create public/templates/posts/edit_page.jinja
create spec/models/post_spec.cr
create spec/endpoints/posts_spec.cr
β
Scaffold Post generated successfully!
Step 6: Create the Database Migration
Generate a migration for the posts table:
azu generate migration create_posts_table title:string content:text published:boolean
Output:
π οΈ Generating migration: create_posts_table
create db/migrations/20231214_120000_create_posts_table.cr
β
Migration create_posts_table generated successfully!
Run the migration:
azu db migrate
Output:
π Running migrations...
migrate 20231214_120000_create_posts_table.cr
β
All migrations completed successfully!
Step 7: Explore Your Application
The development server should automatically reload your application. Visit these URLs:
Homepage:
http://localhost:3000
Posts Index:
http://localhost:3000/posts
New Post:
http://localhost:3000/posts/new
Generated Files Explained
1. Model (src/models/post.cr
)
src/models/post.cr
)require "cql"
class Post < CQL::Model
db_table "posts"
field title : String
field content : String
field published : Boolean = false
validate :title, presence: true, length: {min: 1, max: 255}
validate :content, presence: true
end
2. Endpoint (src/endpoints/posts/index_endpoint.cr
)
src/endpoints/posts/index_endpoint.cr
)class Posts::IndexEndpoint
include Azu::Endpoint
def call(request)
posts = Post.all
index_page = Posts::IndexPage.new(posts: posts)
index_page.render
end
end
3. Contract (src/contracts/posts/create_contract.cr
)
src/contracts/posts/create_contract.cr
)struct Posts::CreateContract
include Azu::Request
validate title, presence: true, length: {min: 1, max: 255}
validate content, presence: true
validate published, inclusion: [true, false]
end
4. Page (src/pages/posts/index_page.cr
)
src/pages/posts/index_page.cr
)class Posts::IndexPage
include Azu::Page
def initialize(@posts : Array(Post))
end
def render
template("posts/index_page.jinja", {
"posts" => @posts.map(&.to_h)
})
end
end
Step 8: Test Your Application
Run the test suite:
crystal spec
Output:
π§ͺ Running tests...
Post
β should be valid with valid attributes
β should validate presence of title
β should validate presence of content
Posts::IndexEndpoint
β should return all posts
β should render index page
Finished in 0.045 seconds
5 examples, 0 failures
Step 9: Add Sample Data
Seed your database with sample data:
# Edit db/seed.cr
cat > db/seed.cr << 'EOF'
require "../src/models/**"
# Create sample posts
Post.create!(
title: "Welcome to My Blog",
content: "This is my first blog post using Azu!",
published: true
)
Post.create!(
title: "Getting Started with Crystal",
content: "Crystal is an amazing language for web development...",
published: true
)
Post.create!(
title: "Draft Post",
content: "This is a draft post that's not published yet.",
published: false
)
puts "β
Sample data created successfully!"
EOF
# Run the seed
azu db:seed
Output:
π± Seeding database...
β
Sample data created successfully!
Step 10: Customize Your Application
Add Custom Styling
Edit public/assets/css/cover.css
to customize your application's appearance:
/* Add custom styles */
.blog-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 2rem 0;
}
.post-card {
border: 1px solid #e9ecef;
border-radius: 0.5rem;
padding: 1.5rem;
margin-bottom: 1rem;
transition: transform 0.2s;
}
.post-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
Add a Custom Endpoint
Generate a custom endpoint for published posts only:
azu generate endpoint published_posts
Edit the generated endpoint:
# src/endpoints/published_posts/index_endpoint.cr
class PublishedPosts::IndexEndpoint
include Azu::Endpoint
def call(request)
published_posts = Post.where(published: true)
index_page = PublishedPosts::IndexPage.new(posts: published_posts)
index_page.render
end
end
Next Steps
Congratulations! You've successfully created your first Azu application. Here's what you can explore next:
π― Immediate Next Steps
Add Authentication - Secure your blog
Add Real-time Features - Live comments or reactions
Create an API - Build a REST API for your blog
Add Testing - Write comprehensive tests
π Learn More
Command Reference - All available CLI commands
Generators Guide - Detailed generator documentation
Development Workflows - Common development patterns
Configuration - Advanced configuration options
π οΈ Advanced Features
Database Relationships - Model associations
Background Jobs - Async processing
Deployment - Deploy to production
Performance Optimization - Scale your application
π Community Examples
Blog Tutorial - Extended blog with user authentication
API Tutorial - Build a complete REST API
Chat Tutorial - Real-time chat application
Troubleshooting
Server Won't Start
# Check for compilation errors
crystal build src/main.cr
# Check database connection
azu db:create
Port Already in Use
# Use a different port
azu serve --port 4000
Database Connection Error
# Verify database is running
sudo systemctl status postgresql # Linux
brew services list | grep postgres # macOS
# Check database configuration
cat src/initializers/database.cr
Hot Reloading Not Working
# Restart the server
# Make sure you're editing files in the src/ directory
Congratulations! π You've built your first Azu application. The development server will automatically reload when you make changes, so start experimenting and building something amazing!
Need Help? Check out the troubleshooting guide or create an issue on GitHub.
Last updated