Skip to main content

Examples

Complete examples demonstrating common use cases for the Fiber HTTP client.

Basic Authentication

Send credentials via the Authorization header:
package main

import (
    "encoding/base64"
    "fmt"
    "github.com/gofiber/fiber/v3/client"
)

func main() {
    c := client.New()

    credentials := base64.StdEncoding.EncodeToString([]byte("john:doe"))
    
    resp, err := c.Get("http://localhost:3000", client.Config{
        Header: map[string]string{
            "Authorization": "Basic " + credentials,
        },
    })
    if err != nil {
        panic(err)
    }
    defer resp.Close()

    fmt.Printf("Status: %d\n", resp.StatusCode())
    fmt.Println(string(resp.Body()))
}

TLS Configuration

Make HTTPS requests with custom TLS settings:
package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "os"
    "github.com/gofiber/fiber/v3/client"
)

func main() {
    c := client.New()

    // Load system cert pool
    certPool, err := x509.SystemCertPool()
    if err != nil {
        panic(err)
    }

    // Add custom certificate
    cert, err := os.ReadFile("ssl.cert")
    if err != nil {
        panic(err)
    }

    certPool.AppendCertsFromPEM(cert)
    
    // Configure TLS
    c.SetTLSConfig(&tls.Config{
        RootCAs: certPool,
        MinVersion: tls.VersionTLS12,
    })

    resp, err := c.Get("https://localhost:3000")
    if err != nil {
        panic(err)
    }
    defer resp.Close()

    fmt.Println(string(resp.Body()))
}

Using HostClient

Create a client for a specific host:
package main

import (
    "log"
    "time"
    "github.com/gofiber/fiber/v3/client"
    "github.com/valyala/fasthttp"
)

func main() {
    hc := &fasthttp.HostClient{
        Addr:                "api.internal:443",
        IsTLS:               true,
        MaxConnDuration:     30 * time.Second,
        MaxIdleConnDuration: 10 * time.Second,
        MaxConns:            100,
    }

    c := client.NewWithHostClient(hc)

    resp, err := c.Get("https://api.internal:443/status")
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Close()

    log.Printf("Status: %d\n", resp.StatusCode())
    log.Printf("Body: %s\n", resp.Body())
}

Load Balancing with LBClient

Distribute requests across multiple servers:
package main

import (
    "log"
    "time"
    "github.com/gofiber/fiber/v3/client"
    "github.com/valyala/fasthttp"
)

func main() {
    lb := &fasthttp.LBClient{
        Timeout: 2 * time.Second,
        Clients: []fasthttp.BalancingClient{
            &fasthttp.HostClient{Addr: "edge-1.internal:8080"},
            &fasthttp.HostClient{Addr: "edge-2.internal:8080"},
            &fasthttp.HostClient{Addr: "edge-3.internal:8080"},
        },
    }

    c := client.NewWithLBClient(lb)

    // Requests are automatically distributed across all hosts
    for i := 0; i < 10; i++ {
        resp, err := c.Get("http://service.internal/api")
        if err != nil {
            log.Fatal(err)
        }
        
        log.Printf("Request %d: Status %d\n", i+1, resp.StatusCode())
        resp.Close()
    }
}
Store and reuse cookies between requests:

Set Cookies

package main

import (
    "fmt"
    "github.com/gofiber/fiber/v3/client"
)

func main() {
    jar := client.AcquireCookieJar()
    defer client.ReleaseCookieJar(jar)

    c := client.New()
    c.SetCookieJar(jar)

    // Set cookies manually
    jar.SetKeyValueBytes("httpbin.org", []byte("session"), []byte("abc123"))
    jar.SetKeyValueBytes("httpbin.org", []byte("user"), []byte("john"))

    resp, err := c.Get("https://httpbin.org/cookies")
    if err != nil {
        panic(err)
    }
    defer resp.Close()

    fmt.Println(string(resp.Body()))
    // Output: {"cookies": {"session": "abc123", "user": "john"}}
}

Receive and Reuse Cookies

package main

import (
    "fmt"
    "github.com/gofiber/fiber/v3/client"
    "github.com/valyala/fasthttp"
)

func main() {
    jar := client.AcquireCookieJar()
    defer client.ReleaseCookieJar(jar)

    c := client.New()
    c.SetCookieJar(jar)

    // First request sets cookies
    _, err := c.Get("https://httpbin.org/cookies/set/session/abc123")
    if err != nil {
        panic(err)
    }

    // Second request automatically includes cookies
    resp, err := c.Get("https://httpbin.org/cookies")
    if err != nil {
        panic(err)
    }
    defer resp.Close()

    fmt.Println(string(resp.Body()))
    // Output: {"cookies": {"session": "abc123"}}

    // Access cookies from jar
    uri := fasthttp.AcquireURI()
    defer fasthttp.ReleaseURI(uri)
    uri.SetHost("httpbin.org")
    uri.SetPath("/cookies")
    
    fmt.Printf("Stored cookies: %s\n", jar.Get(uri))
    // Output: Stored cookies: [session=abc123; path=/]
}

GitHub API Client

Build a simple GitHub API client:
package main

import (
    "fmt"
    "github.com/gofiber/fiber/v3/client"
)

type Repository struct {
    Name        string `json:"name"`
    FullName    string `json:"full_name"`
    Description string `json:"description"`
    Homepage    string `json:"homepage"`
    Stars       int    `json:"stargazers_count"`
    Forks       int    `json:"forks_count"`
    Owner       struct {
        Login string `json:"login"`
    } `json:"owner"`
}

func main() {
    c := client.New()
    c.SetBaseURL("https://api.github.com")
    c.SetHeader("Accept", "application/vnd.github.v3+json")
    c.SetUserAgent("Fiber-Client/1.0")

    resp, err := c.Get("/repos/gofiber/fiber")
    if err != nil {
        panic(err)
    }
    defer resp.Close()

    var repo Repository
    if err := resp.JSON(&repo); err != nil {
        panic(err)
    }

    fmt.Printf("Repository: %s\n", repo.FullName)
    fmt.Printf("Description: %s\n", repo.Description)
    fmt.Printf("Homepage: %s\n", repo.Homepage)
    fmt.Printf("Owner: %s\n", repo.Owner.Login)
    fmt.Printf("Stars: %d\n", repo.Stars)
    fmt.Printf("Forks: %d\n", repo.Forks)
}

File Upload

Upload files using multipart/form-data:
package main

import (
    "fmt"
    "github.com/gofiber/fiber/v3/client"
)

func main() {
    c := client.New()

    resp, err := c.R().
        SetFormData("description", "My uploaded file").
        SetFormData("category", "documents").
        AddFile("/path/to/document.pdf").
        AddFile("/path/to/image.jpg").
        Post("https://api.example.com/upload")
    
    if err != nil {
        panic(err)
    }
    defer resp.Close()

    fmt.Printf("Upload Status: %d\n", resp.StatusCode())
    fmt.Println(string(resp.Body()))
}

Streaming Large Files

Download large files efficiently:
package main

import (
    "fmt"
    "github.com/gofiber/fiber/v3/client"
)

func main() {
    c := client.New()
    c.SetStreamResponseBody(true)

    resp, err := c.Get("https://example.com/largefile.zip")
    if err != nil {
        panic(err)
    }
    defer resp.Close()

    // Save directly to file without loading into memory
    if err := resp.Save("/downloads/largefile.zip"); err != nil {
        panic(err)
    }

    fmt.Println("File downloaded successfully")
}

Retry Logic

Implement custom retry logic with hooks:
package main

import (
    "fmt"
    "time"
    "github.com/gofiber/fiber/v3/client"
)

func main() {
    c := client.New()

    maxRetries := 3
    retryCount := 0

    c.AddResponseHook(func(c *client.Client, resp *client.Response, req *client.Request) error {
        if resp.StatusCode() >= 500 && retryCount < maxRetries {
            retryCount++
            delay := time.Duration(retryCount) * time.Second
            
            fmt.Printf("Request failed with status %d, retrying in %v (attempt %d/%d)\n",
                resp.StatusCode(), delay, retryCount, maxRetries)
            
            time.Sleep(delay)
            // Return error to trigger retry
            return fmt.Errorf("retrying request")
        }
        retryCount = 0
        return nil
    })

    resp, err := c.Get("https://api.example.com/unstable-endpoint")
    if err != nil {
        panic(err)
    }
    defer resp.Close()

    fmt.Printf("Success after %d retries\n", retryCount)
}

Request Logging

Log all requests and responses:
package main

import (
    "fmt"
    "time"
    "github.com/gofiber/fiber/v3/client"
)

func main() {
    c := client.New()

    var requestTime time.Time

    // Log outgoing requests
    c.AddRequestHook(func(c *client.Client, r *client.Request) error {
        requestTime = time.Now()
        fmt.Printf("[%s] %s %s\n", requestTime.Format(time.RFC3339), r.Method(), r.URL())
        return nil
    })

    // Log responses
    c.AddResponseHook(func(c *client.Client, resp *client.Response, req *client.Request) error {
        duration := time.Since(requestTime)
        fmt.Printf("[%s] %s %s -> %d (%v)\n",
            time.Now().Format(time.RFC3339),
            req.Method(),
            req.URL(),
            resp.StatusCode(),
            duration,
        )
        return nil
    })

    resp, err := c.Get("https://httpbin.org/get")
    if err != nil {
        panic(err)
    }
    defer resp.Close()
}

JSON API with Error Handling

Complete example with proper error handling:
package main

import (
    "fmt"
    "github.com/gofiber/fiber/v3/client"
)

type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

type APIError struct {
    Error   string `json:"error"`
    Message string `json:"message"`
    Status  int    `json:"status"`
}

func (e *APIError) Error() string {
    return fmt.Sprintf("API error %d: %s - %s", e.Status, e.Error, e.Message)
}

func GetUser(c *client.Client, id int) (*User, error) {
    resp, err := c.R().
        SetPathParam("id", fmt.Sprintf("%d", id)).
        Get("/users/:id")
    if err != nil {
        return nil, err
    }
    defer resp.Close()

    // Handle error responses
    if resp.StatusCode() != 200 {
        var apiErr APIError
        if err := resp.JSON(&apiErr); err != nil {
            return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode(), resp.Status())
        }
        apiErr.Status = resp.StatusCode()
        return nil, &apiErr
    }

    // Parse success response
    var user User
    if err := resp.JSON(&user); err != nil {
        return nil, fmt.Errorf("failed to parse response: %w", err)
    }

    return &user, nil
}

func main() {
    c := client.New()
    c.SetBaseURL("https://api.example.com/v1")
    c.SetHeader("Authorization", "Bearer your-token")

    user, err := GetUser(c, 123)
    if err != nil {
        if apiErr, ok := err.(*APIError); ok {
            fmt.Printf("API Error: %s\n", apiErr.Message)
        } else {
            fmt.Printf("Error: %v\n", err)
        }
        return
    }

    fmt.Printf("User: %s (%s)\n", user.Name, user.Email)
}

Context and Cancellation

Use context for request cancellation:
package main

import (
    "context"
    "fmt"
    "time"
    "github.com/gofiber/fiber/v3/client"
)

func main() {
    c := client.New()

    // Create a context with timeout
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()

    resp, err := c.R().
        SetContext(ctx).
        Get("https://httpbin.org/delay/10") // This endpoint delays 10 seconds
    
    if err != nil {
        if ctx.Err() == context.DeadlineExceeded {
            fmt.Println("Request timed out")
        } else {
            fmt.Printf("Error: %v\n", err)
        }
        return
    }
    defer resp.Close()

    fmt.Printf("Status: %d\n", resp.StatusCode())
}

Next Steps

Overview

Return to client overview

API Reference

Explore the full API

Build docs developers (and LLMs) love