From f792a7d5d66b748b21b34d4e19c5a692f79ed660 Mon Sep 17 00:00:00 2001 From: RW Date: Sat, 6 Dec 2025 12:52:14 +0100 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=93=92=20docs:=20clarify=20client=20m?= =?UTF-8?q?igration=20examples?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/whats_new.md | 124 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/docs/whats_new.md b/docs/whats_new.md index b6b036a6827..3b08627b425 100644 --- a/docs/whats_new.md +++ b/docs/whats_new.md @@ -846,6 +846,30 @@ The default redirect status code has been updated from `302 Found` to `303 See O The Gofiber client has been completely rebuilt. It includes numerous new features such as Cookiejar, request/response hooks, and more. You can take a look to [client docs](./client/rest.md) to see what's new with the client. +### Configuration improvements + +The v3 client centralizes common configuration on the client instance and lets you override it per request with `client.Config`. +You can define base URLs, defaults (headers, cookies, path parameters, timeouts), and toggle path normalization once, while still +using axios-style helpers for each call. + +```go +cc := client.New(). + SetBaseURL("https://api.service.local"). + AddHeader("Authorization", "Bearer "). + SetTimeout(5 * time.Second). + SetPathParam("tenant", "acme") + +resp, err := cc.Get("/users/:tenant/:id", client.Config{ + PathParam: map[string]string{"id": "42"}, + Param: map[string]string{"include": "profile"}, + DisablePathNormalizing: true, +}) +if err != nil { + panic(err) +} +fmt.Println(resp.StatusCode(), resp.String()) +``` + ### Fasthttp transport integration - `client.NewWithHostClient` and `client.NewWithLBClient` allow you to plug existing `fasthttp` clients directly into Fiber while keeping retries, redirects, and hook logic consistent. @@ -2152,6 +2176,106 @@ import "github.com/gofiber/fiber/v3/client" +**Common migrations**: + +1. **Shared defaults instead of per-call mutation**: Move headers and timeouts into the reusable client and override with `client.Config` when needed. + +
+ Example + + ```go + // Before + status, body, errs := fiber.Get("https://api.example.com/users"). + Set("Authorization", "Bearer "+token). + Timeout(5 * time.Second). + String() + if len(errs) > 0 { + return fmt.Errorf("request failed: %v", errs) + } + fmt.Println(status, body) + ``` + + ```go + // After + cli := client.New(). + AddHeader("Authorization", "Bearer "+token). + SetTimeout(5 * time.Second) + + resp, err := cli.Get("https://api.example.com/users") + if err != nil { + return err + } + fmt.Println(resp.StatusCode(), resp.String()) + ``` + +
+ +2. **Body handling**: Replace `Agent.JSON(...).Struct(&dst)` with request bodies through `client.Config` (or `Request.SetJSON`) and decode the response via `Response.JSON`. + +
+ Example + + ```go + // Before + var created user + status, _, errs := fiber.Post("https://api.example.com/users"). + JSON(payload). + Struct(&created) + if len(errs) > 0 { + return fmt.Errorf("request failed: %v", errs) + } + fmt.Println(status, created) + ``` + + ```go + // After + resp, err := client.New().Post("https://api.example.com/users", client.Config{ + Body: payload, + }) + if err != nil { + return err + } + + var created user + if err := resp.JSON(&created); err != nil { + return fmt.Errorf("decode failed: %w", err) + } + fmt.Println(resp.StatusCode(), created) + ``` + +
+ +3. **Path and query parameters**: Use the new path/query helpers instead of manually formatting URLs. + +
+ Example + + ```go + // Before + code, body, errs := fiber.Get(fmt.Sprintf("https://api.example.com/users/%s", id)). + QueryString("active=true"). + String() + if len(errs) > 0 { + return fmt.Errorf("request failed: %v", errs) + } + fmt.Println(code, body) + ``` + + ```go + // After + cli := client.New().SetBaseURL("https://api.example.com") + resp, err := cli.Get("/users/:id", client.Config{ + PathParam: map[string]string{"id": id}, + Param: map[string]string{"active": "true"}, + }) + if err != nil { + return err + } + fmt.Println(resp.StatusCode(), resp.String()) + ``` + +
+ ### 🛠️ Utils {#utils-migration} Fiber v3 removes the in-repo `utils` package in favor of the external [`github.com/gofiber/utils/v2`](https://github.com/gofiber/utils) module. From 320ce575de708a3d6d6948eeaeb4397f442d23b7 Mon Sep 17 00:00:00 2001 From: RW Date: Sat, 6 Dec 2025 13:07:05 +0100 Subject: [PATCH 2/4] docs: broaden client migration coverage --- docs/whats_new.md | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/docs/whats_new.md b/docs/whats_new.md index 3b08627b425..85de2f3d416 100644 --- a/docs/whats_new.md +++ b/docs/whats_new.md @@ -2276,6 +2276,80 @@ import "github.com/gofiber/fiber/v3/client" +4. **Agent helpers**: `Agent.Bytes`, `AcquireAgent`, and `Agent.Parse` have been removed. Reuse a `client.Client` instance (or pool requests/responses directly) and access response data through the new typed helpers. + +
+ Example + + ```go + // Before + agent := fiber.AcquireAgent() + status, body, errs := agent.Get("https://api.example.com/users").Bytes() + fiber.ReleaseAgent(agent) + if len(errs) > 0 { + return fmt.Errorf("request failed: %v", errs) + } + + var users []user + if err := fiber.Parse(body, &users); err != nil { + return fmt.Errorf("parse failed: %w", err) + } + fmt.Println(status, len(users)) + ``` + + ```go + // After + cli := client.New() + resp, err := cli.Get("https://api.example.com/users") + if err != nil { + return err + } + defer resp.Close() + + var users []user + if err := resp.JSON(&users); err != nil { + return fmt.Errorf("decode failed: %w", err) + } + fmt.Println(resp.StatusCode(), len(users)) + ``` + + :::tip + If you need pooling, use `client.AcquireRequest`, `client.AcquireResponse`, and their corresponding release functions around a long-lived `client.Client` instead of the removed agent pool. + ::: + +
+ +5. **Fiber-level shortcuts**: The `fiber.Get`, `fiber.Post`, and similar top-level helpers are no longer exposed from the main module. Use the client package equivalents (`client.Get`, `client.Post`, etc.) which call the shared default client (or pass your own client instance for custom defaults). + +
+ Example + + ```go + // Before + status, body, errs := fiber.Get("https://api.example.com/health").String() + if len(errs) > 0 { + return fmt.Errorf("request failed: %v", errs) + } + fmt.Println(status, body) + ``` + + ```go + // After + resp, err := client.Get("https://api.example.com/health") + if err != nil { + return err + } + defer resp.Close() + + fmt.Println(resp.StatusCode(), resp.String()) + ``` + + :::note + The `client.Get`/`client.Post` helpers use `client.C()` (the default shared client). For custom defaults, construct a client with `client.New()` and invoke its methods instead. + ::: + +
+ ### 🛠️ Utils {#utils-migration} Fiber v3 removes the in-repo `utils` package in favor of the external [`github.com/gofiber/utils/v2`](https://github.com/gofiber/utils) module. From 64eb643f0727ba2c68be992e0dd9e09b579e78c2 Mon Sep 17 00:00:00 2001 From: RW Date: Sat, 6 Dec 2025 15:31:21 +0100 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=93=92=20docs:=20reuse=20client=20ins?= =?UTF-8?q?tance=20in=20migration=20snippet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/whats_new.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/whats_new.md b/docs/whats_new.md index 85de2f3d416..08654d0ff6c 100644 --- a/docs/whats_new.md +++ b/docs/whats_new.md @@ -2229,7 +2229,9 @@ import "github.com/gofiber/fiber/v3/client" ```go // After - resp, err := client.New().Post("https://api.example.com/users", client.Config{ + cli := client.New() + + resp, err := cli.Post("https://api.example.com/users", client.Config{ Body: payload, }) if err != nil { From be468ca6c7dccef8ea14939a5297762dee16c5e4 Mon Sep 17 00:00:00 2001 From: RW Date: Sat, 6 Dec 2025 15:55:48 +0100 Subject: [PATCH 4/4] docs: close client responses --- docs/whats_new.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/whats_new.md b/docs/whats_new.md index 08654d0ff6c..054f6b68c29 100644 --- a/docs/whats_new.md +++ b/docs/whats_new.md @@ -867,6 +867,7 @@ resp, err := cc.Get("/users/:tenant/:id", client.Config{ if err != nil { panic(err) } +defer resp.Close() fmt.Println(resp.StatusCode(), resp.String()) ``` @@ -2205,6 +2206,7 @@ import "github.com/gofiber/fiber/v3/client" if err != nil { return err } + defer resp.Close() fmt.Println(resp.StatusCode(), resp.String()) ``` @@ -2237,6 +2239,7 @@ import "github.com/gofiber/fiber/v3/client" if err != nil { return err } + defer resp.Close() var created user if err := resp.JSON(&created); err != nil { @@ -2273,6 +2276,7 @@ import "github.com/gofiber/fiber/v3/client" if err != nil { return err } + defer resp.Close() fmt.Println(resp.StatusCode(), resp.String()) ```