Backend Development Guide

Overview

Weber's backend is built with Go, providing a fast, reliable, and scalable server-side framework. The backend follows a modular architecture with clear separation of concerns.

Project Structure

backend/
├── app/          # Core application logic
├── route/        # HTTP route handlers
├── http/         # HTTP client utilities
├── model/        # Data models
├── database/     # Database operations
├── logger/       # Logging system
├── ads/          # Advertisement integration
├── domain/       # Domain-specific logic
└── misc/         # Miscellaneous utilities

App Module

The app module contains core application functionality:

App Initialization

import "weber/backend/app"

// Create a new app instance
webApp := app.New()

// Configure the app
webApp.SetDebugMode(true)
webApp.LoadTemplates("./webroot")

// Start the server
webApp.Run(":8080")

Key Components

  • app.go - Core application struct and methods
  • config/ - Configuration management
  • cache/ - Caching layer
  • template/ - Template engine integration
  • page/ - Page rendering utilities
  • param/ - Request parameter handling

Routing

Weber uses a flexible routing system with support for various HTTP methods:

// In route/route.go
func SetupRoutes(app *app.App) {
    // Static routes
    app.GET("/", index.Handler)
    app.GET("/about", about.Handler)
    
    // Dynamic routes
    app.GET("/news/:id", news.DetailHandler)
    app.GET("/football/:slug", football.Handler)
    
    // API routes
    app.POST("/api/login", login.Handler)
    app.GET("/api/news", news.APIHandler)
}

Route Handlers

func Handler(ctx *app.Context) {
    // Get URL parameters
    id := ctx.Param("id")
    
    // Get query parameters
    page := ctx.Query("page")
    
    // Render template
    ctx.Render("template.html", map[string]interface{}{
        "title": "Page Title",
        "data": data,
    })
}

HTTP Client

Weber includes a built-in HTTP client for making external requests:

import "weber/backend/http"

// Make a GET request
response, err := http.Get("https://api.example.com/data")
if err != nil {
    // Handle error
}

// With caching
cachedResponse, err := http.GetWithCache(
    "https://api.example.com/data",
    time.Hour, // Cache duration
)

Features

  • Built-in caching support
  • Automatic retry logic
  • Timeout configuration
  • Response compression

Models

Data models define the structure of your application data:

// model/news.go
type News struct {
    ID          int       `json:"id"`
    Title       string    `json:"title"`
    Content     string    `json:"content"`
    Category    string    `json:"category"`
    PublishedAt time.Time `json:"published_at"`
    Author      string    `json:"author"`
    ImageURL    string    `json:"image_url"`
}

// Fetch news from API
func FetchNews(category string, page int) ([]News, error) {
    // Implementation
}

Available Models

  • News - News article data
  • Category - Content categories
  • Football - Football-related data
  • Discover - Content discovery
  • Taboola - Advertisement data

Logger

Weber provides a comprehensive logging system:

import "weber/backend/logger"

// Initialize logger
log := logger.New("app")

// Log levels
log.Debug("Debug message")
log.Info("Info message")
log.Warn("Warning message")
log.Error("Error message")

// Structured logging
log.WithFields(logger.Fields{
    "user_id": 123,
    "action": "login",
}).Info("User logged in")

Logger Features

  • Multiple log levels (Debug, Info, Warn, Error)
  • Structured logging with fields
  • File and console output
  • Log rotation
  • Performance optimized

Configuration

Configuration is managed through JSON files and the config module:

// config/dev.json
{
    "server": {
        "port": 8080,
        "host": "localhost"
    },
    "database": {
        "host": "localhost",
        "port": 5432,
        "name": "weber_dev"
    },
    "cache": {
        "enabled": true,
        "ttl": 3600
    }
}
// Load configuration
cfg, err := config.Load("dev")
if err != nil {
    log.Fatal(err)
}

// Access configuration
port := cfg.Server.Port
dbHost := cfg.Database.Host

Middleware

Create custom middleware for request processing:

func LoggingMiddleware(next app.HandlerFunc) app.HandlerFunc {
    return func(ctx *app.Context) {
        start := time.Now()
        
        // Process request
        next(ctx)
        
        // Log request
        duration := time.Since(start)
        log.WithFields(logger.Fields{
            "method": ctx.Method(),
            "path": ctx.Path(),
            "duration": duration,
        }).Info("Request processed")
    }
}

// Apply middleware
app.Use(LoggingMiddleware)

Error Handling

Consistent error handling across the application:

func Handler(ctx *app.Context) {
    data, err := fetchData()
    if err != nil {
        ctx.Error(500, "Failed to fetch data")
        log.Error("Data fetch failed", err)
        return
    }
    
    ctx.JSON(200, data)
}

// Custom error responses
func NotFoundHandler(ctx *app.Context) {
    ctx.Render("404.html", map[string]interface{}{
        "path": ctx.Path(),
    })
}

Testing

Weber includes testing utilities for backend code:

// app_test.go
func TestHandler(t *testing.T) {
    app := app.New()
    app.GET("/test", TestHandler)
    
    // Create test request
    req := httptest.NewRequest("GET", "/test", nil)
    w := httptest.NewRecorder()
    
    // Execute request
    app.ServeHTTP(w, req)
    
    // Assert response
    if w.Code != 200 {
        t.Errorf("Expected 200, got %d", w.Code)
    }
}

Best Practices

  • Use structured logging - Always include context with log messages
  • Handle errors gracefully - Provide meaningful error messages
  • Implement caching - Cache expensive operations and external API calls
  • Write tests - Test route handlers and critical business logic
  • Use configuration - Avoid hardcoding values, use config files
  • Monitor performance - Use the logger to track request durations
  • Validate input - Always validate and sanitize user input

Next Steps