Application Framework

A complete web framework built on the Rivaas router. Includes integrated observability, lifecycle management, and sensible defaults for production-ready applications.

The Rivaas App package provides a high-level framework with pre-configured observability, graceful shutdown, and common middleware for rapid application development.

Overview

The App package is a complete web framework built on top of the Rivaas router. It provides a simple API for building web applications. It includes integrated observability with metrics, tracing, and logging. It has lifecycle management, graceful shutdown, and common middleware patterns.

Key Features

  • Complete Framework - Pre-configured with sensible defaults for rapid development.
  • Integrated Observability - Built-in metrics with Prometheus/OTLP, tracing with OpenTelemetry, and structured logging with slog.
  • Request Binding & Validation - Automatic request parsing with validation strategies.
  • OpenAPI Generation - Automatic OpenAPI spec generation with Swagger UI.
  • Lifecycle Hooks - OnStart, OnReady, OnShutdown, OnStop for initialization and cleanup.
  • Health Endpoints - Kubernetes-compatible liveness and readiness probes.
  • Graceful Shutdown - Proper server shutdown with configurable timeouts.
  • Environment-Aware - Development and production modes with appropriate defaults.

When to Use

Use App Package When

  • Building a complete web application - Need a full framework with all features included.
  • Want integrated observability - Metrics and tracing configured out of the box.
  • Need quick development - Sensible defaults help you start immediately.
  • Building a REST API - Pre-configured with common middleware and patterns.
  • Prefer convention over configuration - Defaults that work well together.

Use Router Package Directly When

  • Building a library or framework - Need full control over the routing layer.
  • Have custom observability setup - Already using specific metrics or tracing solutions.
  • Maximum performance is critical - Want zero overhead from default middleware.
  • Need complete flexibility - Don’t want any opinions or defaults imposed.
  • Integrating into existing systems - Need to fit into established patterns.

Performance Note: The app package adds about 1-2% latency compared to using the router directly. See Router Performance for baseline numbers. However, it provides significant development speed and maintainability benefits. This comes through integrated observability and sensible defaults.

Quick Start

Simple Application

Create a minimal application with defaults:

package main

import (
    "context"
    "log"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    
    "rivaas.dev/app"
)

func main() {
    // Create app with defaults
    a, err := app.New()
    if err != nil {
        log.Fatalf("Failed to create app: %v", err)
    }

    // Register routes
    a.GET("/", func(c *app.Context) {
        c.JSON(http.StatusOK, map[string]string{
            "message": "Hello from Rivaas App!",
        })
    })

    // Setup graceful shutdown
    ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
    defer cancel()

    // Start server with graceful shutdown
    if err := a.Start(ctx); err != nil {
        log.Fatalf("Server error: %v", err)
    }
}

Create a production-ready application with full observability:

package main

import (
    "context"
    "log"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
    
    "rivaas.dev/app"
    "rivaas.dev/logging"
    "rivaas.dev/metrics"
    "rivaas.dev/tracing"
)

func main() {
    // Create app with full observability
    a, err := app.New(
        app.WithServiceName("my-api"),
        app.WithServiceVersion("v1.0.0"),
        app.WithEnvironment("production"),
        // Observability: logging, metrics, tracing
        app.WithObservability(
            app.WithLogging(logging.WithJSONHandler()),
            app.WithMetrics(), // Prometheus is default
            app.WithTracing(tracing.WithOTLP("localhost:4317")),
            app.WithExcludePaths("/livez", "/readyz", "/metrics"),
        ),
        // Health endpoints: GET /livez (liveness), GET /readyz (readiness)
        app.WithHealthEndpoints(
            app.WithHealthTimeout(800 * time.Millisecond),
            app.WithReadinessCheck("database", func(ctx context.Context) error {
                return db.PingContext(ctx)
            }),
        ),
        // Server configuration
        app.WithServer(
            app.WithReadTimeout(15 * time.Second),
            app.WithWriteTimeout(15 * time.Second),
        ),
    )
    if err != nil {
        log.Fatalf("Failed to create app: %v", err)
    }

    // Register routes
    a.GET("/users/:id", func(c *app.Context) {
        userID := c.Param("id")
        
        // Request-scoped logger with automatic context
        c.Logger().Info("processing request", "user_id", userID)
        
        c.JSON(http.StatusOK, map[string]any{
            "user_id":    userID,
            "name":       "John Doe",
            "trace_id":   c.TraceID(),
        })
    })

    // Setup graceful shutdown
    ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
    defer cancel()

    // Start server
    if err := a.Start(ctx); err != nil {
        log.Fatalf("Server error: %v", err)
    }
}

Learning Path

Follow this structured path to master the Rivaas App framework:

1. Getting Started

Start with the basics:

2. Request Handling

Handle requests effectively:

  • Context - Use the app context for binding, validation, and error handling
  • Routing - Organize routes with groups, versioning, and static files
  • Middleware - Add cross-cutting concerns with built-in middleware

3. Observability

Monitor your application:

4. Production Readiness

Prepare for production:

  • Lifecycle - Use lifecycle hooks for initialization and cleanup
  • Server - Configure HTTP, HTTPS, and mTLS servers with graceful shutdown
  • OpenAPI - Generate OpenAPI specs and Swagger UI automatically

5. Testing & Migration

Test and migrate:

  • Testing - Test your routes and handlers without starting a server
  • Migration - Migrate from the router package to the app package
  • Examples - Complete working examples and patterns

Common Use Cases

The Rivaas App excels in these scenarios:

  • REST APIs - Full-featured JSON APIs with observability and validation
  • Microservices - Cloud-native services with health checks and graceful shutdown
  • Web Applications - Complete web apps with middleware and lifecycle management
  • Production Services - Production-ready defaults with integrated monitoring

Next Steps

Need Help?