Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 204 additions & 0 deletions docs/whats_new.md
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,31 @@ 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 <token>").
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)
}
Comment thread
ReneWerner87 marked this conversation as resolved.
defer resp.Close()
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.
Expand Down Expand Up @@ -2152,6 +2177,185 @@ import "github.com/gofiber/fiber/v3/client"

</details>

**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.

<details>
<summary>Example</summary>

```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
}
Comment thread
ReneWerner87 marked this conversation as resolved.
defer resp.Close()
fmt.Println(resp.StatusCode(), resp.String())
```

</details>

2. **Body handling**: Replace `Agent.JSON(...).Struct(&dst)` with request bodies through `client.Config` (or `Request.SetJSON`) and decode the response via `Response.JSON`.

<details>
<summary>Example</summary>

```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
cli := client.New()

resp, err := cli.Post("https://api.example.com/users", client.Config{
Body: payload,
})
if err != nil {
return err
}
Comment thread
ReneWerner87 marked this conversation as resolved.
defer resp.Close()

var created user
if err := resp.JSON(&created); err != nil {
return fmt.Errorf("decode failed: %w", err)
}
fmt.Println(resp.StatusCode(), created)
```

</details>

3. **Path and query parameters**: Use the new path/query helpers instead of manually formatting URLs.

<details>
<summary>Example</summary>

```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
}
Comment thread
ReneWerner87 marked this conversation as resolved.
defer resp.Close()
fmt.Println(resp.StatusCode(), resp.String())
```

</details>

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.

<details>
<summary>Example</summary>

```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.
:::

</details>

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).

<details>
<summary>Example</summary>

```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.
:::

</details>

### 🛠️ 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.
Expand Down