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 -
idautomatically 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!
Quick Links
- π― Start Router Tutorial - Begin learning Lokstra routing
- ποΈ Framework Track - Full enterprise features
- π‘ Examples - Working code samples
- π API Reference - Complete technical docs
Next Steps
Continue Learning:
- Router Basics - Core routing concepts
- Simple Services - Service organization
- Middleware - Cross-cutting concerns
- Configuration - Environment setup
- 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! π