Fiber Framework: High-Performance Web Development
Introduction
Fiber is the fastest web framework for Go, inspired by Express.js. It’s designed for high-performance applications with minimal memory footprint. This guide covers building ultra-fast web applications with Fiber.
Core Concepts
Why Fiber?
- Speed: Fastest web framework for Go
- Familiar API: Similar to Express.js
- Low Memory: Minimal allocations
- Middleware: Extensive middleware ecosystem
- Validation: Built-in validation support
Good: Basic Fiber Setup
Creating a Fiber Application
package main
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/logger"
"github.com/gofiber/fiber/v2/middleware/recover"
)
// โ
GOOD: Basic Fiber application
func main() {
app := fiber.New()
// Middleware
app.Use(logger.New())
app.Use(recover.New())
// Routes
app.Get("/", handleHome)
app.Get("/users/:id", handleGetUser)
app.Post("/users", handleCreateUser)
// Start server
app.Listen(":8080")
}
func handleHome(c *fiber.Ctx) error {
return c.JSON(fiber.Map{
"message": "Welcome to Fiber",
})
}
func handleGetUser(c *fiber.Ctx) error {
id := c.Params("id")
return c.JSON(fiber.Map{
"id": id,
})
}
func handleCreateUser(c *fiber.Ctx) error {
user := struct {
Name string `json:"name"`
Email string `json:"email"`
}{}
if err := c.BodyParser(&user); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": err.Error(),
})
}
return c.Status(fiber.StatusCreated).JSON(user)
}
Route Groups
package main
import (
"github.com/gofiber/fiber/v2"
)
// โ
GOOD: Route grouping in Fiber
func setupRoutes(app *fiber.App) {
// API v1
v1 := app.Group("/api/v1")
{
v1.Get("/health", handleHealth)
v1.Get("/users", handleListUsers)
v1.Post("/users", handleCreateUser)
}
// Protected routes
protected := app.Group("/api/v1")
protected.Use(authMiddleware())
{
protected.Get("/profile", handleProfile)
protected.Put("/profile", handleUpdateProfile)
}
// Admin routes
admin := app.Group("/admin")
admin.Use(authMiddleware(), adminMiddleware())
{
admin.Get("/stats", handleStats)
admin.Delete("/users/:id", handleDeleteUser)
}
}
func handleHealth(c *fiber.Ctx) error {
return c.JSON(fiber.Map{"status": "ok"})
}
func handleListUsers(c *fiber.Ctx) error {
return c.JSON([]string{})
}
func handleCreateUser(c *fiber.Ctx) error {
return c.Status(fiber.StatusCreated).JSON(fiber.Map{"created": true})
}
func handleProfile(c *fiber.Ctx) error {
return c.JSON(fiber.Map{"profile": "data"})
}
func handleUpdateProfile(c *fiber.Ctx) error {
return c.JSON(fiber.Map{"updated": true})
}
func handleStats(c *fiber.Ctx) error {
return c.JSON(fiber.Map{"stats": "data"})
}
func handleDeleteUser(c *fiber.Ctx) error {
return c.JSON(fiber.Map{"deleted": true})
}
func authMiddleware() fiber.Handler {
return func(c *fiber.Ctx) error {
token := c.Get("Authorization")
if token == "" {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"error": "Unauthorized",
})
}
return c.Next()
}
}
func adminMiddleware() fiber.Handler {
return func(c *fiber.Ctx) error {
// Check admin role
return c.Next()
}
}
Good: Middleware
Creating Fiber Middleware
package main
import (
"github.com/gofiber/fiber/v2"
"log"
"time"
)
// โ
GOOD: Logging middleware
func loggingMiddleware(c *fiber.Ctx) error {
start := time.Now()
err := c.Next()
duration := time.Since(start)
log.Printf("%s %s %d %v",
c.Method(),
c.Path(),
c.Response().StatusCode(),
duration,
)
return err
}
// โ
GOOD: Rate limiting middleware
func rateLimitMiddleware(c *fiber.Ctx) error {
// Implement rate limiting
return c.Next()
}
// โ
GOOD: CORS middleware
func corsMiddleware(c *fiber.Ctx) error {
c.Set("Access-Control-Allow-Origin", "*")
c.Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
c.Set("Access-Control-Allow-Headers", "Content-Type")
if c.Method() == "OPTIONS" {
return c.SendStatus(fiber.StatusNoContent)
}
return c.Next()
}
// โ
GOOD: Error handling middleware
func errorHandlingMiddleware(c *fiber.Ctx) error {
defer func() {
if err := recover(); err != nil {
log.Printf("Panic: %v", err)
c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": "Internal server error",
})
}
}()
return c.Next()
}
Good: Request Handling
Binding and Validation
package main
import (
"github.com/gofiber/fiber/v2"
)
// โ
GOOD: Struct with validation tags
type User struct {
Name string `json:"name" validate:"required,min=3,max=50"`
Email string `json:"email" validate:"required,email"`
Age int `json:"age" validate:"min=0,max=150"`
}
// โ
GOOD: Parse JSON body
func handleCreateUserWithValidation(c *fiber.Ctx) error {
user := new(User)
if err := c.BodyParser(user); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
}
return c.Status(fiber.StatusCreated).JSON(user)
}
// โ
GOOD: Extract query parameters
func handleSearch(c *fiber.Ctx) error {
query := c.Query("q")
limit := c.Query("limit", "10")
return c.JSON(fiber.Map{
"query": query,
"limit": limit,
})
}
// โ
GOOD: Extract path parameters
func handleGetByID(c *fiber.Ctx) error {
id := c.Params("id")
return c.JSON(fiber.Map{
"id": id,
})
}
// โ
GOOD: Set response headers
func handleWithHeaders(c *fiber.Ctx) error {
c.Set("X-Custom-Header", "value")
return c.JSON(fiber.Map{"message": "ok"})
}
// โ
GOOD: Set cookies
func handleCookies(c *fiber.Ctx) error {
c.Cookie(&fiber.Cookie{
Name: "session",
Value: "abc123",
Expires: time.Now().Add(24 * time.Hour),
HTTPOnly: true,
})
return c.JSON(fiber.Map{"message": "cookie set"})
}
Advanced Patterns
Custom Error Handler
package main
import (
"github.com/gofiber/fiber/v2"
)
// โ
GOOD: Custom error handler
type ErrorResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Details string `json:"details,omitempty"`
}
func customErrorHandler(c *fiber.Ctx, err error) error {
code := fiber.StatusInternalServerError
message := "Internal server error"
if e, ok := err.(*fiber.Error); ok {
code = e.Code
message = e.Message
}
return c.Status(code).JSON(ErrorResponse{
Code: code,
Message: message,
})
}
// โ
GOOD: Using custom error handler
func setupErrorHandling(app *fiber.App) {
app.Use(func(c *fiber.Ctx) error {
return c.Next()
})
}
File Upload
package main
import (
"github.com/gofiber/fiber/v2"
)
// โ
GOOD: Handle file upload
func handleFileUpload(c *fiber.Ctx) error {
file, err := c.FormFile("file")
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "No file provided",
})
}
// Save file
if err := c.SaveFile(file, "./uploads/"+file.Filename); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": "Upload failed",
})
}
return c.JSON(fiber.Map{
"filename": file.Filename,
"size": file.Size,
})
}
Performance Optimization
Efficient Request Handling
package main
import (
"github.com/gofiber/fiber/v2"
)
// โ
GOOD: Reuse buffers for performance
func handleLargeResponse(c *fiber.Ctx) error {
// Fiber automatically manages buffers efficiently
return c.JSON(fiber.Map{
"data": "large response",
})
}
// โ
GOOD: Stream large files
func handleStreamFile(c *fiber.Ctx) error {
return c.SendFile("./large-file.bin")
}
// โ
GOOD: Use connection pooling
func setupDatabase(app *fiber.App) {
// Configure connection pooling
}
Best Practices
1. Use Middleware for Cross-Cutting Concerns
// โ
GOOD: Middleware for logging, auth, etc.
app.Use(loggingMiddleware)
app.Use(authMiddleware())
// โ BAD: Repeating logic in handlers
func handler(c *fiber.Ctx) error {
// Log
// Check auth
// Do work
}
2. Validate Input
// โ
GOOD: Use validation tags
type Request struct {
Email string `json:"email" validate:"required,email"`
Age int `json:"age" validate:"min=0,max=150"`
}
// โ BAD: Manual validation
type BadRequest struct {
Email string
Age int
}
3. Handle Errors Consistently
// โ
GOOD: Consistent error responses
return c.Status(fiber.StatusBadRequest).JSON(ErrorResponse{
Code: fiber.StatusBadRequest,
Message: "Invalid input",
})
// โ BAD: Inconsistent error handling
return c.SendString("Error")
Resources
- Fiber Documentation: https://docs.gofiber.io/
- Fiber GitHub: https://github.com/gofiber/fiber
- Fiber Middleware: https://docs.gofiber.io/api/middleware/
Summary
Fiber is the fastest web framework for Go, perfect for high-performance applications. Use route groups for organization, middleware for cross-cutting concerns, and proper validation for robust applications. Fiber’s speed and low memory footprint make it ideal for building scalable web services.
Comments