Fiber Samples

Fiber Go web framework examples including routing, middleware, templates, WebSocket, database integration, and performance optimization

Key Facts

Category
Web Frameworks
Items
1
Format Families
sample

Sample Overview

Fiber Go web framework examples including routing, middleware, templates, WebSocket, database integration, and performance optimization This sample set belongs to Web Frameworks and can be used to test related workflows inside Elysia Tools.

💻 Fiber Hello World go

🟢 simple

Basic Fiber web server setup with routing, middleware, handlers, and essential Go web development patterns

// Fiber Hello World Examples

package main

import (
    "fmt"
    "log"
    "time"

    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/template/html/v2"
    "github.com/gofiber/websocket/v2"
    "github.com/gofiber/fiber/v2/middleware/cors"
    "github.com/gofiber/fiber/v2/middleware/logger"
    "github.com/gofiber/fiber/v2/middleware/recover"
)

// 1. Basic Fiber Server
func basicServer() {
    app := fiber.New()

    app.Get("/", func(c *fiber.Ctx) error {
        return c.JSON(fiber.Map{
            "message": "Hello, Fiber!",
            "time":    time.Now(),
        })
    })

    log.Fatal(app.Listen(":3000"))
}

// 2. Fiber with Middleware
func serverWithMiddleware() {
    app := fiber.New(fiber.Config{
        // Prefork enables multiple processes to handle requests
        Prefork: true,
    })

    // Middleware
    app.Use(recover.New())           // Recover from panics
    app.Use(logger.New())            // HTTP request logger
    app.Use(cors.New())              // Enable CORS

    // Custom middleware
    app.Use(func(c *fiber.Ctx) error {
        c.Set("X-Server", "Fiber")
        return c.Next()
    })

    // Timing middleware
    app.Use(func(c *fiber.Ctx) error {
        start := time.Now()
        err := c.Next()
        duration := time.Since(start)

        c.Set("X-Response-Time", duration.String())
        return err
    })

    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("Hello from Fiber with middleware!")
    })

    log.Fatal(app.Listen(":3000"))
}

// 3. REST API with Fiber
type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
    Age   int    `json:"age"`
}

// In-memory database (use proper database in production)
var users = []User{
    {ID: 1, Name: "John Doe", Email: "[email protected]", Age: 30},
    {ID: 2, Name: "Jane Smith", Email: "[email protected]", Age: 25},
    {ID: 3, Name: "Bob Johnson", Email: "[email protected]", Age: 35},
}

func restAPI() {
    app := fiber.New()

    // Get all users
    app.Get("/api/users", func(c *fiber.Ctx) error {
        return c.JSON(fiber.Map{
            "users": users,
            "total": len(users),
        })
    })

    // Get user by ID
    app.Get("/api/users/:id", func(c *fiber.Ctx) error {
        id, err := c.ParamsInt("id")
        if err != nil {
            return c.Status(400).JSON(fiber.Map{
                "error": "Invalid user ID",
            })
        }

        for _, user := range users {
            if user.ID == id {
                return c.JSON(user)
            }
        }

        return c.Status(404).JSON(fiber.Map{
            "error": "User not found",
        })
    })

    // Create new user
    app.Post("/api/users", func(c *fiber.Ctx) error {
        user := new(User)
        if err := c.BodyParser(user); err != nil {
            return c.Status(400).JSON(fiber.Map{
                "error": "Cannot parse JSON",
            })
        }

        // Validation
        if user.Name == "" || user.Email == "" {
            return c.Status(400).JSON(fiber.Map{
                "error": "Name and email are required",
            })
        }

        user.ID = len(users) + 1
        users = append(users, *user)

        return c.Status(201).JSON(user)
    })

    // Update user
    app.Put("/api/users/:id", func(c *fiber.Ctx) error {
        id, err := c.ParamsInt("id")
        if err != nil {
            return c.Status(400).JSON(fiber.Map{
                "error": "Invalid user ID",
            })
        }

        var updateUser User
        if err := c.BodyParser(&updateUser); err != nil {
            return c.Status(400).JSON(fiber.Map{
                "error": "Cannot parse JSON",
            })
        }

        for i, user := range users {
            if user.ID == id {
                if updateUser.Name != "" {
                    users[i].Name = updateUser.Name
                }
                if updateUser.Email != "" {
                    users[i].Email = updateUser.Email
                }
                if updateUser.Age > 0 {
                    users[i].Age = updateUser.Age
                }
                return c.JSON(users[i])
            }
        }

        return c.Status(404).JSON(fiber.Map{
            "error": "User not found",
        })
    })

    // Delete user
    app.Delete("/api/users/:id", func(c *fiber.Ctx) error {
        id, err := c.ParamsInt("id")
        if err != nil {
            return c.Status(400).JSON(fiber.Map{
                "error": "Invalid user ID",
            })
        }

        for i, user := range users {
            if user.ID == id {
                users = append(users[:i], users[i+1:]...)
                return c.SendStatus(204)
            }
        }

        return c.Status(404).JSON(fiber.Map{
            "error": "User not found",
        })
    })

    log.Fatal(app.Listen(":3000"))
}

// 4. Fiber with Grouped Routes and Middleware
func groupedRoutes() {
    app := fiber.New()

    // API v1 group with middleware
    v1 := app.Group("/api/v1", func(c *fiber.Ctx) error {
        c.Set("API-Version", "1.0")
        return c.Next()
    })

    // Users group
    userRoutes := v1.Group("/users")
    userRoutes.Get("/", func(c *fiber.Ctx) error {
        return c.JSON(users)
    })

    userRoutes.Post("/", func(c *fiber.Ctx) error {
        user := new(User)
        if err := c.BodyParser(user); err != nil {
            return c.Status(400).JSON(fiber.Map{"error": err.Error()})
        }
        user.ID = len(users) + 1
        users = append(users, *user)
        return c.Status(201).JSON(user)
    })

    // Admin group with authentication middleware
    admin := v1.Group("/admin", func(c *fiber.Ctx) error {
        token := c.Get("Authorization")
        if token != "Bearer admin-token" {
            return c.Status(401).JSON(fiber.Map{"error": "Unauthorized"})
        }
        return c.Next()
    })

    admin.Get("/stats", func(c *fiber.Ctx) error {
        return c.JSON(fiber.Map{
            "total_users": len(users),
            "server_time": time.Now(),
        })
    })

    log.Fatal(app.Listen(":3000"))
}

// 5. Fiber with Static Files and Templates

func staticFilesAndTemplates() {
    // Initialize template engine
    engine := html.New("./views", ".html")

    app := fiber.New(fiber.Config{
        Views: engine,
    })

    // Serve static files
    app.Static("/", "./public")

    // Template route
    app.Get("/welcome", func(c *fiber.Ctx) error {
        return c.Render("welcome", fiber.Map{
            "Title": "Welcome to Fiber",
            "Name":  "Developer",
        })
    })

    // Dynamic template
    app.Get("/user/:name", func(c *fiber.Ctx) error {
        return c.Render("user", fiber.Map{
            "Name": c.Params("name"),
            "Time": time.Now(),
        })
    })

    log.Fatal(app.Listen(":3000"))
}

// 6. Fiber with WebSocket Support

func websocketExample() {
    app := fiber.New()

    // WebSocket middleware
    app.Use("/ws", func(c *fiber.Ctx) error {
        // IsWebSocketUpgrade returns true if the client
        // requested upgrade to the WebSocket protocol.
        if websocket.IsWebSocketUpgrade(c) {
            c.Locals("allowed", true)
            return c.Next()
        }
        return fiber.ErrUpgradeRequired
    })

    // WebSocket route
    app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {
        // c.Locals is added to the *websocket.Conn
        log.Println(c.Locals("allowed"))  // true
        log.Println(c.Params("id"))       // 123

        var (
            mt  int
            msg []byte
            err error
        )
        for {
            if mt, msg, err = c.ReadMessage(); err != nil {
                log.Println("read:", err)
                break
            }
            log.Printf("recv: %s", msg)

            if err = c.WriteMessage(mt, msg); err != nil {
                log.Println("write:", err)
                break
            }
        }
    }))

    // HTTP route
    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("WebSocket example. Connect to ws://localhost:3000/ws/123")
    })

    log.Fatal(app.Listen(":3000"))
}

// 7. Fiber with Database Integration (GORM)
import (
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

type Product struct {
    gorm.Model
    Name        string  `json:"name"`
    Description string  `json:"description"`
    Price       float64 `json:"price"`
    Stock       int     `json:"stock"`
}

func databaseIntegration() {
    app := fiber.New()

    // Initialize database
    db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
    if err != nil {
        panic("Failed to connect database")
    }

    // Auto migrate the schema
    db.AutoMigrate(&Product{})

    // Seed data
    db.Create(&Product{Name: "Laptop", Description: "High-performance laptop", Price: 999.99, Stock: 50})
    db.Create(&Product{Name: "Mouse", Description: "Wireless optical mouse", Price: 29.99, Stock: 200})

    // API Routes
    app.Get("/api/products", func(c *fiber.Ctx) error {
        var products []Product
        db.Find(&products)
        return c.JSON(products)
    })

    app.Get("/api/products/:id", func(c *fiber.Ctx) error {
        id := c.Params("id")
        var product Product
        result := db.First(&product, id)
        if result.Error != nil {
            return c.Status(404).JSON(fiber.Map{"error": "Product not found"})
        }
        return c.JSON(product)
    })

    app.Post("/api/products", func(c *fiber.Ctx) error {
        product := new(Product)
        if err := c.BodyParser(product); err != nil {
            return c.Status(400).JSON(fiber.Map{"error": err.Error()})
        }

        result := db.Create(product)
        if result.Error != nil {
            return c.Status(400).JSON(fiber.Map{"error": result.Error.Error()})
        }

        return c.Status(201).JSON(product)
    })

    app.Put("/api/products/:id", func(c *fiber.Ctx) error {
        id := c.Params("id")
        var product Product
        result := db.First(&product, id)
        if result.Error != nil {
            return c.Status(404).JSON(fiber.Map{"error": "Product not found"})
        }

        if err := c.BodyParser(&product); err != nil {
            return c.Status(400).JSON(fiber.Map{"error": err.Error()})
        }

        db.Save(&product)
        return c.JSON(product)
    })

    app.Delete("/api/products/:id", func(c *fiber.Ctx) error {
        id := c.Params("id")
        var product Product
        result := db.Delete(&product, id)
        if result.Error != nil {
            return c.Status(404).JSON(fiber.Map{"error": "Product not found"})
        }
        return c.SendStatus(204)
    })

    log.Fatal(app.Listen(":3000"))
}

// 8. Fiber with File Upload
import (
    "os"
    "path/filepath"
)

func fileUpload() {
    app := fiber.New()

    // Ensure upload directory exists
    os.MkdirAll("./uploads", 0755)

    // Single file upload
    app.Post("/upload", func(c *fiber.Ctx) error {
        file, err := c.FormFile("document")
        if err != nil {
            return c.Status(400).JSON(fiber.Map{"error": "No file uploaded"})
        }

        // Save file to uploads directory
        filename := filepath.Base(file.Filename)
        savePath := filepath.Join("./uploads", filename)

        if err := c.SaveFile(file, savePath); err != nil {
            return c.Status(500).JSON(fiber.Map{"error": "Cannot save file"})
        }

        return c.JSON(fiber.Map{
            "message":  "File uploaded successfully",
            "filename": filename,
            "size":     file.Size,
            "path":     savePath,
        })
    })

    // Multiple files upload
    app.Post("/upload/multiple", func(c *fiber.Ctx) error {
        form, err := c.MultipartForm()
        if err != nil {
            return c.Status(400).JSON(fiber.Map{"error": "Cannot parse form"})
        }

        files := form.File["documents"]
        var uploadedFiles []string

        for _, file := range files {
            filename := filepath.Base(file.Filename)
            savePath := filepath.Join("./uploads", filename)

            if err := c.SaveFile(file, savePath); err != nil {
                return c.Status(500).JSON(fiber.Map{
                    "error":   "Cannot save file: " + filename,
                    "file":    filename,
                    "message": "Error occurred during file upload",
                })
            }

            uploadedFiles = append(uploadedFiles, filename)
        }

        return c.JSON(fiber.Map{
            "message": "Files uploaded successfully",
            "files":   uploadedFiles,
            "count":   len(uploadedFiles),
        })
    })

    // List uploaded files
    app.Get("/files", func(c *fiber.Ctx) error {
        files, err := os.ReadDir("./uploads")
        if err != nil {
            return c.Status(500).JSON(fiber.Map{"error": "Cannot read uploads directory"})
        }

        var fileList []string
        for _, file := range files {
            fileList = append(fileList, file.Name())
        }

        return c.JSON(fiber.Map{
            "files": fileList,
            "count": len(fileList),
        })
    })

    // Download file
    app.Get("/download/:filename", func(c *fiber.Ctx) error {
        filename := c.Params("filename")
        filePath := filepath.Join("./uploads", filename)

        return c.Download(filePath, filename)
    })

    log.Fatal(app.Listen(":3000"))
}

// 9. Fiber with Authentication and JWT
import (
    "strings"
    "time"

    "github.com/golang-jwt/jwt/v5"
    "github.com/gofiber/fiber/v2/middleware/keyauth"
)

// JWT Claims
type Claims struct {
    UserID   int    `json:"user_id"`
    Username string `json:"username"`
    jwt.RegisteredClaims
}

var jwtSecret = []byte("your-secret-key")

// Mock users
var mockUsers = map[string]string{
    "admin":  "admin123",
    "user":   "user123",
}

func authenticationJWT() {
    app := fiber.New()

    // Login endpoint
    app.Post("/login", func(c *fiber.Ctx) error {
        type LoginRequest struct {
            Username string `json:"username"`
            Password string `json:"password"`
        }

        login := new(LoginRequest)
        if err := c.BodyParser(login); err != nil {
            return c.Status(400).JSON(fiber.Map{"error": "Cannot parse JSON"})
        }

        // Validate credentials (in production, use proper password hashing)
        if password, exists := mockUsers[login.Username]; !exists || password != login.Password {
            return c.Status(401).JSON(fiber.Map{"error": "Invalid credentials"})
        }

        // Generate JWT token
        expirationTime := time.Now().Add(24 * time.Hour)
        claims := &Claims{
            UserID:   1,
            Username: login.Username,
            RegisteredClaims: jwt.RegisteredClaims{
                ExpiresAt: jwt.NewNumericDate(expirationTime),
            },
        }

        token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
        tokenString, err := token.SignedString(jwtSecret)
        if err != nil {
            return c.Status(500).JSON(fiber.Map{"error": "Could not generate token"})
        }

        return c.JSON(fiber.Map{
            "token":     tokenString,
            "expiresAt": expirationTime,
            "user": fiber.Map{
                "username": login.Username,
                "userId":   1,
            },
        })
    })

    // JWT validation middleware
    app.Use(keyauth.New(keyauth.Config{
        KeyLookup: "header:Authorization",
        Validator: func(c *fiber.Ctx, key string) (bool, error) {
            if !strings.HasPrefix(key, "Bearer ") {
                return false, nil
            }

            tokenString := key[7:] // Remove "Bearer " prefix
            claims := &Claims{}

            token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
                return jwtSecret, nil
            })

            if err != nil || !token.Valid {
                return false, nil
            }

            // Store claims in context
            c.Locals("user", claims)
            return true, nil
        },
    }))

    // Protected routes
    app.Get("/profile", func(c *fiber.Ctx) error {
        claims := c.Locals("user").(*Claims)
        return c.JSON(fiber.Map{
            "user_id":  claims.UserID,
            "username": claims.Username,
            "message": "This is protected content",
        })
    })

    // API group
    api := app.Group("/api")
    api.Get("/data", func(c *fiber.Ctx) error {
        return c.JSON(fiber.Map{
            "message": "This is API data",
            "time":    time.Now(),
        })
    })

    log.Fatal(app.Listen(":3000"))
}

// 10. Fiber Production Best Practices
func productionSetup() {
    app := fiber.New(fiber.Config{
        Prefork:       true,              // Enable prefork
        CaseSensitive: true,              // Case sensitive routing
        StrictRouting: true,              // Strict routing
        ServerHeader:  "Fiber",          // Server header
        AppName:       "Fiber App v1.0", // App name
        // Read timeout
        ReadTimeout: 5 * time.Second,
        // Write timeout
        WriteTimeout: 10 * time.Second,
        // Idle timeout
        IdleTimeout: 60 * time.Second,
    })

    // Security middleware
    app.Use(recover.New())
    app.Use(cors.New(cors.Config{
        AllowOrigins:     "https://example.com",
        AllowMethods:     "GET,POST,PUT,DELETE,OPTIONS",
        AllowHeaders:     "Origin, Content-Type, Accept, Authorization",
        ExposeHeaders:    "Content-Length",
        AllowCredentials: true,
        MaxAge:           86400,
    }))

    // Rate limiting
    app.Use(func(c *fiber.Ctx) error {
        // Simple rate limiting (use proper rate limiting in production)
        // This is just an example
        c.Set("X-RateLimit-Limit", "1000")
        c.Set("X-RateLimit-Remaining", "999")
        return c.Next()
    })

    // Health check endpoint
    app.Get("/health", func(c *fiber.Ctx) error {
        return c.JSON(fiber.Map{
            "status":    "ok",
            "timestamp": time.Now(),
            "version":   "1.0.0",
            "uptime":    time.Since(time.Now()).String(),
        })
    })

    // Readiness check for Kubernetes
    app.Get("/ready", func(c *fiber.Ctx) error {
        // Check database connectivity, external services, etc.
        return c.JSON(fiber.Map{
            "status": "ready",
        })
    })

    // Liveness check for Kubernetes
    app.Get("/live", func(c *fiber.Ctx) error {
        return c.JSON(fiber.Map{
            "status": "alive",
        })
    })

    // Metrics endpoint
    app.Get("/metrics", func(c *fiber.Ctx) error {
        // Return Prometheus-compatible metrics
        metrics := `# HELP http_requests_total The total number of HTTP requests
# TYPE http_requests_total counter
http_requests_total 1234

# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 12.34
`
        c.Set("Content-Type", "text/plain")
        return c.SendString(metrics)
    })

    // Graceful shutdown
    go func() {
        <-time.After(30 * time.Second)
        fmt.Println("Shutting down server...")
        app.Shutdown()
    }()

    log.Fatal(app.Listen(":3000"))
}

func main() {
    // Uncomment the function you want to run
    // basicServer()
    // serverWithMiddleware()
    // restAPI()
    // groupedRoutes()
    // staticFilesAndTemplates()
    // websocketExample()
    // databaseIntegration()
    // fileUpload()
    // authenticationJWT()
    // productionSetup()

    // Default to basic server
    basicServer()
}