Skip to content

Commit 48a764a

Browse files
authored
📒 docs: clarify client migration examples (#3921)
1 parent 3924a62 commit 48a764a

File tree

1 file changed

+204
-0
lines changed

1 file changed

+204
-0
lines changed

docs/whats_new.md

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,31 @@ The default redirect status code has been updated from `302 Found` to `303 See O
846846
The Gofiber client has been completely rebuilt. It includes numerous new features such as Cookiejar, request/response hooks, and more.
847847
You can take a look to [client docs](./client/rest.md) to see what's new with the client.
848848

849+
### Configuration improvements
850+
851+
The v3 client centralizes common configuration on the client instance and lets you override it per request with `client.Config`.
852+
You can define base URLs, defaults (headers, cookies, path parameters, timeouts), and toggle path normalization once, while still
853+
using axios-style helpers for each call.
854+
855+
```go
856+
cc := client.New().
857+
SetBaseURL("https://api.service.local").
858+
AddHeader("Authorization", "Bearer <token>").
859+
SetTimeout(5 * time.Second).
860+
SetPathParam("tenant", "acme")
861+
862+
resp, err := cc.Get("/users/:tenant/:id", client.Config{
863+
PathParam: map[string]string{"id": "42"},
864+
Param: map[string]string{"include": "profile"},
865+
DisablePathNormalizing: true,
866+
})
867+
if err != nil {
868+
panic(err)
869+
}
870+
defer resp.Close()
871+
fmt.Println(resp.StatusCode(), resp.String())
872+
```
873+
849874
### Fasthttp transport integration
850875

851876
- `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 +2177,185 @@ import "github.com/gofiber/fiber/v3/client"
21522177

21532178
</details>
21542179

2180+
**Common migrations**:
2181+
2182+
1. **Shared defaults instead of per-call mutation**: Move headers and timeouts into the reusable client and override with `client.Config` when needed.
2183+
2184+
<details>
2185+
<summary>Example</summary>
2186+
2187+
```go
2188+
// Before
2189+
status, body, errs := fiber.Get("https://api.example.com/users").
2190+
Set("Authorization", "Bearer "+token).
2191+
Timeout(5 * time.Second).
2192+
String()
2193+
if len(errs) > 0 {
2194+
return fmt.Errorf("request failed: %v", errs)
2195+
}
2196+
fmt.Println(status, body)
2197+
```
2198+
2199+
```go
2200+
// After
2201+
cli := client.New().
2202+
AddHeader("Authorization", "Bearer "+token).
2203+
SetTimeout(5 * time.Second)
2204+
2205+
resp, err := cli.Get("https://api.example.com/users")
2206+
if err != nil {
2207+
return err
2208+
}
2209+
defer resp.Close()
2210+
fmt.Println(resp.StatusCode(), resp.String())
2211+
```
2212+
2213+
</details>
2214+
2215+
2. **Body handling**: Replace `Agent.JSON(...).Struct(&dst)` with request bodies through `client.Config` (or `Request.SetJSON`) and decode the response via `Response.JSON`.
2216+
2217+
<details>
2218+
<summary>Example</summary>
2219+
2220+
```go
2221+
// Before
2222+
var created user
2223+
status, _, errs := fiber.Post("https://api.example.com/users").
2224+
JSON(payload).
2225+
Struct(&created)
2226+
if len(errs) > 0 {
2227+
return fmt.Errorf("request failed: %v", errs)
2228+
}
2229+
fmt.Println(status, created)
2230+
```
2231+
2232+
```go
2233+
// After
2234+
cli := client.New()
2235+
2236+
resp, err := cli.Post("https://api.example.com/users", client.Config{
2237+
Body: payload,
2238+
})
2239+
if err != nil {
2240+
return err
2241+
}
2242+
defer resp.Close()
2243+
2244+
var created user
2245+
if err := resp.JSON(&created); err != nil {
2246+
return fmt.Errorf("decode failed: %w", err)
2247+
}
2248+
fmt.Println(resp.StatusCode(), created)
2249+
```
2250+
2251+
</details>
2252+
2253+
3. **Path and query parameters**: Use the new path/query helpers instead of manually formatting URLs.
2254+
2255+
<details>
2256+
<summary>Example</summary>
2257+
2258+
```go
2259+
// Before
2260+
code, body, errs := fiber.Get(fmt.Sprintf("https://api.example.com/users/%s", id)).
2261+
QueryString("active=true").
2262+
String()
2263+
if len(errs) > 0 {
2264+
return fmt.Errorf("request failed: %v", errs)
2265+
}
2266+
fmt.Println(code, body)
2267+
```
2268+
2269+
```go
2270+
// After
2271+
cli := client.New().SetBaseURL("https://api.example.com")
2272+
resp, err := cli.Get("/users/:id", client.Config{
2273+
PathParam: map[string]string{"id": id},
2274+
Param: map[string]string{"active": "true"},
2275+
})
2276+
if err != nil {
2277+
return err
2278+
}
2279+
defer resp.Close()
2280+
fmt.Println(resp.StatusCode(), resp.String())
2281+
```
2282+
2283+
</details>
2284+
2285+
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.
2286+
2287+
<details>
2288+
<summary>Example</summary>
2289+
2290+
```go
2291+
// Before
2292+
agent := fiber.AcquireAgent()
2293+
status, body, errs := agent.Get("https://api.example.com/users").Bytes()
2294+
fiber.ReleaseAgent(agent)
2295+
if len(errs) > 0 {
2296+
return fmt.Errorf("request failed: %v", errs)
2297+
}
2298+
2299+
var users []user
2300+
if err := fiber.Parse(body, &users); err != nil {
2301+
return fmt.Errorf("parse failed: %w", err)
2302+
}
2303+
fmt.Println(status, len(users))
2304+
```
2305+
2306+
```go
2307+
// After
2308+
cli := client.New()
2309+
resp, err := cli.Get("https://api.example.com/users")
2310+
if err != nil {
2311+
return err
2312+
}
2313+
defer resp.Close()
2314+
2315+
var users []user
2316+
if err := resp.JSON(&users); err != nil {
2317+
return fmt.Errorf("decode failed: %w", err)
2318+
}
2319+
fmt.Println(resp.StatusCode(), len(users))
2320+
```
2321+
2322+
:::tip
2323+
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.
2324+
:::
2325+
2326+
</details>
2327+
2328+
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).
2329+
2330+
<details>
2331+
<summary>Example</summary>
2332+
2333+
```go
2334+
// Before
2335+
status, body, errs := fiber.Get("https://api.example.com/health").String()
2336+
if len(errs) > 0 {
2337+
return fmt.Errorf("request failed: %v", errs)
2338+
}
2339+
fmt.Println(status, body)
2340+
```
2341+
2342+
```go
2343+
// After
2344+
resp, err := client.Get("https://api.example.com/health")
2345+
if err != nil {
2346+
return err
2347+
}
2348+
defer resp.Close()
2349+
2350+
fmt.Println(resp.StatusCode(), resp.String())
2351+
```
2352+
2353+
:::note
2354+
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.
2355+
:::
2356+
2357+
</details>
2358+
21552359
### 🛠️ Utils {#utils-migration}
21562360

21572361
Fiber v3 removes the in-repo `utils` package in favor of the external [`github.com/gofiber/utils/v2`](https://github.com/gofiber/utils) module.

0 commit comments

Comments
 (0)