ANAR Web Framework - Complete Documentation

Introduction

ANAR is a powerful Go web framework built on top of GORM and Gin that provides rapid application development through code generation and scaffolding. It follows the convention-over-configuration principle and offers a comprehensive CLI tool for managing your web application lifecycle.

Key Features

  • Rapid Development: Generate models, handlers, and migrations with simple commands
  • GORM Integration: Full ORM support with automatic model parsing
  • Gin Framework: High-performance HTTP web framework
  • Live Reload: Built-in air integration for development
  • Relationship Management: Support for all GORM relationship types
  • Pagination & Search: Built-in pagination and search functionality
  • RESTful APIs: Automatic CRUD operation generation
  • Migration System: Database schema management
  • Modular Architecture: Clean separation of concerns
  • JWT-based authentication support
  • Redis integration
  • SMTP email support
  • S3-compatible storage support
  • Built-in scheduler for background jobs and tasks
  • OAuth login via Facebook, Google, Apple, and GitHub
  • Modular, extensible, and configurable architecture

Architecture

ANAR follows a modular architecture with the following components:

  • CLI Handler: Command processing and routing
  • Generators: Code generation for models, handlers, and migrations
  • Model Parser: Automatic model detection and parsing
  • Project Management: Build and run utilities
  • Configuration: Centralized configuration management

Installation and Setup

Prerequisites

  • Go 1.19 or higher
  • Git
  • Database (PostgreSQL, MySQL, SQLite, etc.)

Installation

  1. Clone or install ANAR:
    go install codeberg.org/anarproject/anar@latest
    
  2. Initialize a new project:
    anar init github.com/yourusername/yourproject
    
  3. Navigate to your project directory:
    cd yourproject
    

Project Settings in ANAR

Every project generated with ANAR comes with a centralized configuration system located in the config/ package. This ensures that all environment variables and project-wide settings are managed in one place. This section explains in detail every available setting, its purpose, defaults, and how to customize it.

Server Settings

The server settings control how your application is served.

  • SERVER_PORT: The port where the HTTP server will run.
    • Default: 8000
    • Example:
      SERVER_PORT=8002
      

When the application runs, it will start listening on http://localhost:8002.

JWT (Authentication)

ANAR provides JWT-based authentication by default.

  • JWT_SECRET: The secret key used to sign JWT tokens.
    • Must be a long, random string for security.
    • Example:
      JWT_SECRET=supersecretkey123
      
  • JWT_EXPIRATION: The lifetime of issued tokens.
    • Format: a duration string (e.g., 24h, 72h).
    • Example:
      JWT_EXPIRATION=72h
      
  • TOKEN_ISSUER: Identifies the token issuer (used in token validation).
    • Example:
      TOKEN_ISSUER=anar-api
      

Database Settings

ANAR integrates with GORM, supporting PostgreSQL, MySQL, SQLite, and SQL Server.

  • DB_DRIVER: Selects the database driver. Options: postgres, mysql, sqlite, sqlserver.
  • DB_HOST: Database host (not needed for SQLite).
  • DB_PORT: Port number (default varies by database).
  • DB_USER: Username.
  • DB_PASSWORD: Password.
  • DB_NAME: Database name.
  • DB_SSLMODE: SSL mode (PostgreSQL only). Common values: disable, require.

Example for PostgreSQL:

DB_DRIVER=postgres
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=password
DB_NAME=anar_db
DB_SSLMODE=disable

For SQLite (no host/port needed):

DB_DRIVER=sqlite
DB_NAME=database.db

CORS (Cross-Origin Resource Sharing)

CORS allows you to define which domains can access your API.

  • CORS_ALLOWED_ORIGINS: A comma-separated list of allowed origins.
    • Example:
      CORS_ALLOWED_ORIGINS=http://localhost:3000,http://example.com
      

If not set, ANAR defaults to allowing requests from * (all origins), which is fine for development but not recommended for production.

Redis Settings

Redis can be used for caching, sessions, and other high-performance storage needs.

  • REDIS_ENABLED: Enables Redis integration (true or false).
  • REDIS_HOST: Hostname of the Redis server.
  • REDIS_PORT: Port of the Redis server.
  • REDIS_TTL: Default time-to-live for cached items, in seconds.

Example:

REDIS_ENABLED=true
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_TTL=60

SMTP (Email)

ANAR supports sending emails via SMTP (e.g., Gmail, Postfix, SendGrid).

  • SMTP_HOST: SMTP server host.
  • SMTP_PORT: SMTP port (587 for TLS, 465 for SSL).
  • SMTP_USER: SMTP username (usually your email).
  • SMTP_PASSWORD: Password or app-specific password.
  • SMTP_FROM: The email address used as the sender.

Example (Gmail):

SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your_email@gmail.com
SMTP_PASSWORD=your_password
SMTP_FROM=your_email@gmail.com

Application Settings

  • APP_URL: Base URL of your application. Used in places where absolute URLs are needed (such as OAuth callbacks, password reset links, etc.).

Example:

APP_URL=http://localhost:8002

S3 Storage (File Uploads)

ANAR supports object storage services like AWS S3 and MinIO for file uploads.

  • S3_ENABLED: Enables or disables S3 integration.
  • S3_ENDPOINT: Endpoint of the storage server (e.g., MinIO http://localhost:9000).
  • S3_REGION: Storage region (e.g., us-east-1).
  • S3_ACCESS_KEY: Access key.
  • S3_SECRET_KEY: Secret key.
  • S3_BUCKET: Default bucket name.
  • S3_USE_SSL: Whether to use SSL (true or false).

Example (MinIO):

S3_ENABLED=true
S3_ENDPOINT=http://localhost:9000
S3_REGION=us-east-1
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin
S3_BUCKET=anar
S3_USE_SSL=false

If you don’t want to use S3, ANAR falls back to local uploads automatically - no extra setup is needed.

OAuth Providers

ANAR comes with built-in support for third-party login via Google, Facebook, Apple, and GitHub.

Each provider requires:

  • Client ID
  • Client Secret
  • Redirect URL (must match the callback URL configured in your provider dashboard)

Example for Google:

GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_REDIRECT_URL=http://localhost:8002/api/auth/google/callback

Similarly, you can configure:

  • FACEBOOK_CLIENT_ID, FACEBOOK_CLIENT_SECRET, FACEBOOK_REDIRECT_URL
  • GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GITHUB_REDIRECT_URL
  • APPLE_CLIENT_ID, APPLE_CLIENT_SECRET, APPLE_REDIRECT_URL

Default Uploads

File uploads work out-of-the-box in ANAR without requiring configuration. If S3 is not enabled, files will be stored locally in the project. Developers can immediately start uploading files using the provided APIs.

Command Line Interface (CLI)

ANAR provides a comprehensive CLI for managing your application. All commands follow the pattern:

anar <command> [arguments]

Available Commands

Project Management

# Initialize a new project
anar init <module_name>

# Build the project
anar build

# Run with live reload (using air)
anar run

Code Generation

# Generate complete project scaffold
anar scaffold

# Generate only handlers
anar handlers

# Generate only migrations
anar migrations

Model Management

# Create a new model
anar model <ModelName> [field:type ...]

# Add fields to existing model
anar add-field-to-model <ModelName> field:type [field:type ...]

# Remove field from existing model
anar remove-field-from-model <ModelName> <FieldName>

Command Examples

# Initialize project
anar init github.com/mycompany/blogapi

# Create models
anar model User name:string email:string age:int
anar model Post title:string content:text user:belongsTo
anar model Category name:string posts:hasMany

# Generate all handlers and migrations
anar scaffold

# Add new field to existing model
anar add-field-to-model User phone:string

# Remove field from model
anar remove-field-from-model User age

# Run the application
anar run

Model Generation and Management

Creating Models

ANAR supports comprehensive model generation with various field types and relationships.

Basic Model Creation

anar model User name:string email:string age:int active:bool

This generates:

type User struct {
    gorm.Model
    Name   string `json:"name"`
    Email  string `json:"email"`
    Age    int    `json:"age"`
    Active bool   `json:"active"`
}

Supported Field Types

Type Go Type Description Example
string string Basic string field name:string
text string Large text field content:text
int / integer int Integer field age:int
uint uint Unsigned integer score:uint
float / decimal float64 Float field price:float
bool / boolean bool Boolean field active:bool
time / datetime time.Time Time field published_at:time
json / jsonb string JSON field metadata:json
uuid string UUID field with auto-generation external_id:uuid
file types.FileField File upload field avatar:file

Special Field Types

  • text: Creates a text field in the database
  • json: Creates a JSON field with appropriate GORM tags
  • uuid: Includes UUID generation functionality
  • file: Specialized field type for file uploads

Model Field Management

Adding Fields to Existing Models

# Add single field
anar add-field-to-model User phone:string

# Add multiple fields
anar add-field-to-model User phone:string verified:bool last_login:time

Removing Fields from Models

anar remove-field-from-model User age

Note: When removing relationship fields, both the foreign key and the relationship struct will be removed automatically.

Model Structure

All generated models include:

  1. gorm.Model: Embedded struct providing ID, CreatedAt, UpdatedAt, DeletedAt
  2. Custom Fields: Your specified fields with appropriate types and tags
  3. JSON Tags: Automatic JSON serialization tags
  4. GORM Tags: Database-specific tags and constraints

Example generated model:

type User struct {
    gorm.Model
    Name      string    `json:"name"`
    Email     string    `json:"email"`
    Age       int       `json:"age"`
    Active    bool      `json:"active"`
    CreatedAt time.Time `json:"created_at"`
    UpdatedAt time.Time `json:"updated_at"`
}

Database Relationships

ANAR supports all GORM relationship types with automatic foreign key and join table management.

Relationship Types

1. BelongsTo Relationship

Creates a foreign key reference to another model.

anar model Post title:string content:text user:belongsTo

Generates:

type Post struct {
    gorm.Model
    Title   string `json:"title"`
    Content string `json:"content" gorm:"type:text"`
    UserID  uint   `json:"user_id"`
    User    User   `json:"user" gorm:"foreignKey:UserID"`
}
2. HasOne Relationship

Creates a one-to-one relationship.

anar model Profile bio:text avatar:string user:hasOne

Generates:

type Profile struct {
    gorm.Model
    Bio    string `json:"bio" gorm:"type:text"`
    Avatar string `json:"avatar"`
    User   User   `json:"user" gorm:"foreignKey:UserID"`
}
3. HasMany Relationship

Creates a one-to-many relationship.

anar model User name:string email:string posts:hasMany

Generates:

type User struct {
    gorm.Model
    Name  string `json:"name"`
    Email string `json:"email"`
    Posts []Post `json:"posts" gorm:"foreignKey:UserID"`
}
4. ManyToMany Relationship

Creates a many-to-many relationship with automatic join table.

anar model User name:string email:string categories:manyToMany

Generates:

type User struct {
    gorm.Model
    Name       string     `json:"name"`
    Email      string     `json:"email"`
    Categories []Category `json:"categories" gorm:"many2many:user_categories;"`
}

Handler Generation

ANAR automatically generates RESTful API handlers for all your models with full CRUD functionality.

Generated Handler Methods

For each model, ANAR generates the following handlers:

1. GetAll (with Pagination)

  • Endpoint: GET /models
  • Features: Pagination, search, filtering
  • Parameters: page, limit, search, sort

2. GetAllSimple (Legacy)

  • Endpoint: GET /models/simple
  • Features: Basic listing without pagination

3. GetByID

  • Endpoint: GET /models/:id
  • Features: Single record retrieval

4. Create

  • Endpoint: POST /models
  • Features: JSON body validation and creation

5. Update

  • Endpoint: PUT /models/:id
  • Features: Partial or full record updates

6. Delete

  • Endpoint: DELETE /models/:id
  • Features: Soft delete support

Handler Generation

# Generate handlers for all models
anar handlers

# Or generate complete scaffold (includes handlers)
anar scaffold

Generated Handler Example

For a User model, ANAR generates user_handler.go:

package handlers

import (
    "github.com/gin-gonic/gin"
    "yourproject/models"
)

// User Handlers

// GetAllUsers handles fetching all users with pagination, search, and filtering
func (h Handler) GetAllUsers(c *gin.Context) {
    // Define which fields can be searched
    searchFields := []string{"name", "email"}
    
    // Use the new paginated method
    h.getAllWithPagination(models.User{}, searchFields, c)
}

// GetAllUsersSimple handles fetching all users without pagination (legacy)
func (h Handler) GetAllUsersSimple(c *gin.Context) {
    h.getAll(models.User{}, c)
}

// GetUserByID handles fetching a single user by ID
func (h Handler) GetUserByID(c *gin.Context) {
    h.getByID(models.User{}, c, "User not found")
}

// AddUser handles creating a new user
func (h Handler) AddUser(c *gin.Context) {
    h.add(models.User{}, c)
}

// UpdateUser handles updating an existing user
func (h Handler) UpdateUser(c *gin.Context) {
    h.update(models.User{}, c, "User not found")
}

// DeleteUser handles deleting a user by ID
func (h Handler) DeleteUser(c *gin.Context) {
    h.delete(models.User{}, c, "User not found")
}

Search and Pagination Features

Pagination Parameters

  • page: Page number (default: 1)
  • limit: Items per page (default: 10)

Search Parameters

  • search: Search term to look for in searchable fields
  • sort: Sort field and direction (e.g., name, -created_at)

Usage Examples

# Get first page with 20 items
GET /users?page=1&limit=20

# Search for users
GET /users?search=john

# Sort by name ascending
GET /users?sort=name

# Sort by creation date descending
GET /users?sort=-created_at

# Combine parameters
GET /users?page=2&limit=15&search=admin&sort=name

Custom Search Fields

ANAR automatically determines searchable fields for each model, but you can customize them by modifying the generated handler:

// Customize searchable fields
searchFields := []string{"name", "email", "phone"}

Migration System

ANAR provides automatic database migration generation based on your models.

Migration Generation

# Generate migrations for all models
anar migrations

# Or generate complete scaffold (includes migrations)
anar scaffold

Generated Migration File

ANAR creates a single auto_migrations.go file containing all model migrations:

package migrations

import (
    "fmt"
    "gorm.io/gorm"
    "yourproject/models"
)

// AutoMigrate runs all model migrations
func AutoMigrate(db *gorm.DB) error {
    fmt.Println("Running auto migrations...")
    
    if err := db.AutoMigrate(&models.User{}); err != nil {
        return fmt.Errorf("failed to migrate User: %w", err)
    }

    if err := db.AutoMigrate(&models.Post{}); err != nil {
        return fmt.Errorf("failed to migrate Post: %w", err)
    }

    fmt.Println("All migrations completed successfully!")
    return nil
}

// DropAllTables drops all model tables (use with caution)
func DropAllTables(db *gorm.DB) error {
    fmt.Println("Dropping all tables...")
    
    // Drop tables in reverse order to handle dependencies
    if err := db.Migrator().DropTable(&models.Post{}); err != nil {
        return fmt.Errorf("failed to drop Post table: %w", err)
    }

    if err := db.Migrator().DropTable(&models.User{}); err != nil {
        return fmt.Errorf("failed to drop User table: %w", err)
    }

    fmt.Println("All tables dropped successfully!")
    return nil
}

// GetModelList returns list of all models being migrated
func GetModelList() []string {
    return []string{"User", "Post"}
}

Migration Features

  1. Auto Migration: Uses GORM’s AutoMigrate for schema synchronization
  2. Dependency Handling: Manages table creation order for relationships
  3. Drop Tables: Provides safe table dropping in reverse order
  4. Model Tracking: Maintains list of all migrated models

Scaffolding System

The scaffolding system generates complete CRUD functionality for your entire application.

Scaffold Generation

anar scaffold

This command:

  1. Parses all models in the models/ directory
  2. Generates handlers for each model
  3. Creates database migrations
  4. Sets up the complete API structure

Custom Scaffold Generators

ANAR supports custom scaffold generators. If you have a custom generator at ./cmd/gen/gen, it will be used instead of the built-in generator.

What Gets Generated

When you run anar scaffold, the following files are created:

  1. Handler Files: handlers/model_handler.go for each model
  2. Migration File: migrations/auto_migrations.go

Example Scaffold Output

Generated 3 handler files in handlers/ directory:
- user_handler.go
- post_handler.go
- category_handler.go

Generated single migration file: migrations/auto_migrations.go
Models included: User, Post, Category

Routes

Every project generated with ANAR comes with a pre-configured routing system located in the file:

routes/routes.go

This file is the central place where all API endpoints (routes) are registered and connected to their corresponding handlers. ANAR uses the Gin framework for routing, so the syntax is both simple and powerful.

Route Structure

Routes in ANAR are organized into three main categories:

  1. Public Routes
    • Accessible without authentication.
    • Typically used for registration, login, or fetching general data.
  2. OAuth Routes
    • Handle login via third-party providers like Google, GitHub, Facebook, or Apple.
  3. Protected Routes
    • Require authentication using the built-in JWT middleware.
    • These routes are ideal for sensitive operations such as adding, updating, or deleting records.

Example of routes/routes.go

package routes

import (
    "github.com/gin-gonic/gin"
    "codeberg.org/anarproject/anar/handlers"
    "codeberg.org/anarproject/anar/middleware/jwt"
    "codeberg.org/anarproject/anar/config"
    "codeberg.org/anarproject/anar/db"
)

func SetupRoutes(r *gin.Engine, database db.Database, config *config.Config) {
    handler := handlers.Init(database, config)
    jwtMiddleware := jwt.NewJWTMiddleware(config)

    api := r.Group("/api")

    // Public routes
    api.POST("/register", handler.Register)
    api.GET("/confirm/:token", handler.ConfirmEmail)
    api.POST("/login", handler.Login)
    api.GET("/users", handler.GetAllUsers)
    api.GET("/users/:id", handler.GetUserByID)

    // OAuth routes
    auth := api.Group("/auth")
    {
        auth.GET("/:provider", handler.OAuthLogin)
        auth.GET("/:provider/callback", handler.OAuthCallback)
    }

    // Protected routes
    protected := api.Group("/")
    protected.Use(jwtMiddleware.AuthRequired())
    {
        protected.POST("/users", handler.AddUser)
        protected.PUT("/users/:id", handler.UpdateUser)
        protected.DELETE("/users/:id", handler.DeleteUser)
    }
}

Adding New Routes

When you create a new model and its handler, you need to manually register routes for it in routes/routes.go.

For example, after generating a Product model and handler:

anar model Product name:string price:float
anar scaffold

You can add routes like this:

api.GET("/products", handler.GetAllProducts)
api.GET("/products/:id", handler.GetProductByID)

protected.POST("/products", handler.AddProduct)
protected.PUT("/products/:id", handler.UpdateProduct)
protected.DELETE("/products/:id", handler.DeleteProduct)

Workflow with Routes

  1. Generate models and handlers using the CLI.
  2. Open routes/routes.go and register the new handler methods.
  3. Run the project to make the new endpoints available:
anar run

Key Notes

  • All public routes can be accessed without authentication.
  • Protected routes are guarded by JWT middleware, requiring a valid token.
  • OAuth routes are automatically supported; you only need to configure providers in your project settings.

Advanced Features

File Upload Support

ANAR includes support for file upload fields using the file type:

anar model User name:string avatar:file

This generates:

type User struct {
    gorm.Model
    Name   string           `json:"name"`
    Avatar types.FileField  `json:"avatar"`
}

JSON Field Support

For storing JSON data:

anar model Settings config:json metadata:jsonb

Generates:

type Settings struct {
    gorm.Model
    Config   string `json:"config" gorm:"type:json"`
    Metadata string `json:"metadata" gorm:"type:json"`
}

UUID Field Support

For UUID fields with automatic generation:

anar model User name:string external_id:uuid

Generates:

type User struct {
    gorm.Model
    Name       string `json:"name"`
    ExternalID string `json:"external_id" gorm:"type:uuid;default:uuid_generate_v4()"`
}

Live Reload Development

ANAR includes integration with Air for live reload during development:

anar run

This:

  1. Automatically installs Air if not present
  2. Starts the application with live reload
  3. Watches for file changes and rebuilds automatically

Best Practices

Model Design

  1. Use descriptive names: Choose clear, meaningful model names
  2. Plan relationships: Design your data model before generating
  3. Consider search fields: Think about which fields users will search
  4. Use appropriate types: Choose the right field types for your data

Development Workflow

  1. Start with models: Design and create your models first
  2. Generate scaffold: Use anar scaffold to generate all code
  3. Customize as needed: Modify generated code to fit your requirements
  4. Use live reload: Develop with anar run for faster iteration

Code Organization

  1. Keep models simple: Focus on data structure in models
  2. Business logic in services: Create service layers for complex logic
  3. Customize handlers: Modify generated handlers for specific needs
  4. Version control: Commit generated code to track changes

Database Management

  1. Use migrations: Always use the migration system
  2. Plan relationships: Design foreign keys and constraints properly
  3. Index important fields: Add database indexes for performance
  4. Backup before changes: Always backup before major migrations

Troubleshooting

Common Issues

1. Model Not Found Errors

Problem: “no models found in models/ directory”

Solutions:

  • Ensure models exist in the models/ directory
  • Check that models follow proper Go struct syntax
  • Verify the models.go file exists and is properly formatted

2. Import Path Issues

Problem: Import path errors in generated files

Solutions:

  • Run anar init with the correct module name
  • Ensure go.mod has the right module path
  • Check that package names match directory structure

3. Generation Failures

Problem: Code generation fails with permission errors

Solutions:

  • Check directory permissions
  • Ensure you’re in the project root directory
  • Verify Go workspace is properly configured

4. Relationship Errors

Problem: Foreign key or relationship errors

Solutions:

  • Ensure related models exist before creating relationships
  • Check that foreign key names follow conventions
  • Verify relationship types are correct

Debugging Tips

  1. Verbose Output: Check console output for detailed error messages
  2. File Permissions: Ensure proper read/write permissions
  3. Go Module: Verify go.mod is properly configured
  4. Directory Structure: Follow the standard project layout

Getting Help

  1. Check Documentation: Review this documentation thoroughly
  2. Examine Generated Code: Look at generated files for patterns
  3. Issue Reporting: Report bugs with detailed reproduction steps

Examples and Use Cases

Example 1: Blog API

Complete blog API with authentication:

# Initialize project
anar init github.com/mycompany/blog-api

# Create models
anar model Category name:string description:text
anar model Post title:string content:text published:bool user:belongsTo
anar model Comment content:text user:belongsTo post:belongsTo

# Create many-to-many relationship
anar add-field-to-model Post categories:manyToMany

# Generate all handlers and migrations
anar scaffold

# Run the application
anar run

Example 2: E-commerce API

Product catalog with inventory management:

# Initialize
anar init github.com/store/ecommerce-api

# Create core models
anar model Category name:string description:text
anar model Product name:string description:text price:float stock:int category:belongsTo
anar model Customer name:string email:string phone:string
anar model Order total:float status:string customer:belongsTo
anar model OrderItem quantity:int price:float order:belongsTo product:belongsTo

# Generate scaffold
anar scaffold

Example 3: Social Media API

User profiles and content sharing:

# Initialize
anar init github.com/social/api

# Create user and profile models
anar model Profile bio:text avatar:file location:string user:belongsTo

# Create content models
anar model Post content:text image:file likes:int user:belongsTo
anar model Comment content:text user:belongsTo post:belongsTo

# Create social features
anar model Follow follower:belongsTo following:belongsTo
anar model Like user:belongsTo post:belongsTo

# Generate complete API
anar scaffold

Conclusion

ANAR provides a comprehensive solution for rapid Go web application development. By leveraging code generation, intelligent scaffolding, and convention-over-configuration principles, developers can focus on business logic rather than boilerplate code.

The framework’s strength lies in its simplicity and power - with just a few commands, you can generate a complete RESTful API with CRUD operations, database migrations, and relationship management.

Whether you’re building a simple blog API or a complex enterprise application, ANAR’s flexible architecture and comprehensive feature set provide the foundation for scalable, maintainable web applications.

For continued learning and development with ANAR:

  1. Practice with Examples: Work through the provided examples
  2. Customize Generated Code: Adapt the generated code to your specific needs
  3. Explore Advanced Features: Experiment with relationships and special field types
  4. Build Real Applications: Apply ANAR to actual projects
  5. Contribute Back: Share improvements and extensions with the community

Happy coding with ANAR!