Router Guide - Lokstra as HTTP Router

Use Lokstra like Echo, Gin, or Chi - Fast, flexible HTTP routing without the complexity of dependency injection frameworks

Welcome to Track 1 of Lokstra! Here you’ll learn to use Lokstra as a simple, powerful HTTP router with:

  • βœ… Flexible Handler Signatures - 29+ different handler forms
  • βœ… Clean Middleware Support - Composable, reusable middleware
  • βœ… Group Routing - API versioning and organization
  • βœ… Type-Safe Parameters - Automatic parameter binding and validation
  • βœ… Zero Framework Lock-in - Use as much or as little as you need

Router Comparison

Feature Lokstra Router Echo Gin Chi
Handler Forms 29+ signatures Fixed signatures Fixed signatures Fixed signatures
Middleware βœ… Composable βœ… Good βœ… Good βœ… Excellent
Parameter Binding βœ… Auto-validation Manual Manual Manual
Type Safety βœ… Struct-based Manual casting Manual casting Manual casting
Learning Curve Low Medium Low Low

πŸ‘‰ Why choose Lokstra over other routers?


Quick Router Example

Simple API in 10 lines:

package main

import "github.com/primadi/lokstra"

func main() {
    r := lokstra.NewRouter("api")
    
    r.GET("/", func() string {
        return "Hello, Lokstra Router!"
    })
    
    r.GET("/users/{id}", func(id string) string {
        return fmt.Sprintf("User ID: %s", id)
    })
    
    app := lokstra.NewApp("my-api", ":8080", r)
    app.Run(30 * time.Second)
}

What’s special:

  • βœ… No manual parameter extraction - id automatically injected
  • βœ… Multiple return types - string, JSON, error handling
  • βœ… Clean syntax - No complex structs or handlers
  • βœ… Type safety - Compile-time parameter validation

Learning Path

🎯 1. Router Basics

Learn the foundation of Lokstra routing with flexible handler signatures.

What you’ll learn:

  • βœ… 29+ handler signature patterns
  • βœ… Path parameters and query strings
  • βœ… Request/Response handling patterns
  • βœ… HTTP method routing (GET, POST, PUT, DELETE)

Key concepts:

// Simple handlers
r.GET("/ping", func() string { return "pong" })

// With parameters
r.GET("/users/{id}", func(id int) (*User, error) {
    return getUserByID(id)
})

// With request context
r.POST("/users", func(ctx *request.Context, user *User) error {
    return ctx.Api.Created(createUser(user))
})

πŸ›‘οΈ 2. Simple Services

Add basic service layer without complex dependency injection.

What you’ll learn:

  • βœ… Simple service patterns
  • βœ… Manual dependency management
  • βœ… Service organization
  • βœ… Testing strategies

Key concepts:

type UserService struct {
    db *Database
}

func NewUserService(db *Database) *UserService {
    return &UserService{db: db}
}

func (s *UserService) GetByID(id int) (*User, error) {
    return s.db.QueryOne("SELECT * FROM users WHERE id = ?", id)
}

// Simple registration
userService := NewUserService(db)
r.GET("/users/{id}", userService.GetByID)

πŸ”— 3. Middleware

Add cross-cutting concerns like logging, authentication, and CORS.

What you’ll learn:

  • βœ… Built-in middleware (CORS, logging, recovery)
  • βœ… Custom middleware creation
  • βœ… Middleware composition and ordering
  • βœ… Request/Response transformation

Key concepts:

// Built-in middleware
r.Use(cors.Middleware("*"))
r.Use(logging.Middleware())
r.Use(recovery.Middleware())

// Custom middleware
r.Use(func(next lokstra.Handler) lokstra.Handler {
    return func(ctx *request.Context) error {
        start := time.Now()
        err := next(ctx)
        log.Printf("Request took %v", time.Since(start))
        return err
    }
})

// Group middleware
api := r.Group("/api/v1")
api.Use(authMiddleware)
api.GET("/protected", protectedHandler)

βš™οΈ 4. Configuration

Simple configuration patterns without YAML complexity.

What you’ll learn:

  • βœ… Environment variables
  • βœ… Configuration structs
  • βœ… Development vs production setup
  • βœ… Secret management

Key concepts:

type Config struct {
    Port     string `env:"PORT" default:"8080"`
    Database string `env:"DATABASE_URL" required:"true"`
    Debug    bool   `env:"DEBUG" default:"false"`
}

func loadConfig() *Config {
    cfg := &Config{}
    env.Parse(cfg)
    return cfg
}

πŸš€ 5. App & Server

Application lifecycle, graceful shutdown, and server management.

What you’ll learn:

  • βœ… Application setup and lifecycle
  • βœ… Graceful shutdown handling
  • βœ… Health checks and monitoring
  • βœ… Production deployment patterns

🎯 6. Putting it Together

Complete example combining all router concepts.

What you’ll learn:

  • βœ… Project structure best practices
  • βœ… Testing strategies
  • βœ… Performance optimization
  • βœ… Production deployment

Router Benefits

vs Manual HTTP Handling

  • βœ… No manual mux setup - Clean router abstraction
  • βœ… Automatic parameter binding - No more mux.Vars(r)
  • βœ… Type-safe handlers - Compile-time validation
  • βœ… Built-in middleware - No need to write common functionality

vs Other Go Routers

  • βœ… More flexible handlers - 29+ signature patterns vs fixed signatures
  • βœ… Automatic validation - Struct tags for parameter validation
  • βœ… Clean middleware - Simple function composition
  • βœ… No framework lock-in - Use incrementally

vs Full Frameworks

  • βœ… Simpler learning curve - Just routing, no DI complexity
  • βœ… Faster development - Less boilerplate, more productivity
  • βœ… Smaller binary - No unused framework features
  • βœ… Easy migration - Can upgrade to full framework later

Why Lokstra Router?

🎯 Flexibility Without Complexity

// All of these work automatically:
r.GET("/simple", func() string { return "ok" })
r.GET("/with-error", func() (string, error) { return "ok", nil })
r.GET("/with-context", func(ctx *request.Context) error { 
    return ctx.Api.Ok("ok") 
})
r.GET("/with-params/{id}", func(id int) (*User, error) { 
    return getUser(id) 
})
r.POST("/with-body", func(user *CreateUserRequest) (*User, error) { 
    return createUser(user) 
})

πŸ›‘οΈ Type Safety by Default

type GetUserParams struct {
    ID int `path:"id" validate:"required,min=1"`
}

// Automatic validation - no manual checking needed!
r.GET("/users/{id}", func(p *GetUserParams) (*User, error) {
    // p.ID is already validated as positive integer
    return userService.GetByID(p.ID)
})

πŸ”— Composable Middleware

// Build middleware chains easily
authChain := lokstra.Chain(
    cors.Middleware("*"),
    logging.Middleware(),
    auth.Middleware("jwt-secret"),
)

api := r.Group("/api/v1")
api.Use(authChain)

πŸ“¦ Incremental Adoption

// Start simple
r.GET("/ping", func() string { return "pong" })

// Add services gradually
r.GET("/users/{id}", userService.GetByID)

// Add middleware when needed
r.Use(logging.Middleware())

// Upgrade to full framework later if needed

When to Use Router Track

Choose Router Track when you’re building:

  • βœ… Simple APIs with straightforward routing needs
  • βœ… Microservices that don’t need complex DI
  • βœ… Rapid prototypes that need fast development
  • βœ… Team projects where not everyone knows DI patterns
  • βœ… Migration projects from other Go routers
  • βœ… Learning projects to understand routing fundamentals

If you need auto-generated APIs, dependency injection, or enterprise features, consider Framework Track instead.


Router vs Framework Track

Aspect Router Track Framework Track
Complexity Simple, straightforward More concepts to learn
Setup Time Minutes Hours
DI Pattern Manual, simple Automatic, type-safe
API Generation Manual routing Auto-generated from services
Configuration Environment variables YAML + code
Team Size 1-5 developers 5+ developers
Use Case Simple APIs, microservices Enterprise applications

Not sure which track? Start with Router Track - you can always upgrade to Framework Track later!



Next Steps

Continue Learning:

  1. Router Basics - Core routing concepts
  2. Simple Services - Service organization
  3. Middleware - Cross-cutting concerns
  4. Configuration - Environment setup
  5. Complete Example - Production-ready app

Build Real Projects:

  • Build REST APIs with clean routing
  • Add authentication and middleware
  • Create microservices with simple patterns
  • Deploy to production with confidence

Ready to start routing? β†’ Router Basics

Need enterprise features? β†’ Framework Guide


Simple routing. Clean code. Fast development.

Start with Router Track and grow into Framework Track when you need it! πŸš€