Releases: goforj/httpx
v2.0.0
Why v2 Introduces Breaking Changes
1. Explicit Error Handling
v2 removes implicit error fields and requires explicit (T, error) returns. This enforces correct error handling and prevents silent failures.
2. Clearer API Semantics
Request helpers now return only decoded values, not wrapped result objects. This simplifies usage and aligns with standard Go patterns.
3. Consistent Function Signatures
All request helpers (Get, Post, Put, etc.) now share a uniform signature, reducing cognitive overhead and improving discoverability.
4. Improved Internal Architecture
The new design removes legacy abstraction layers, making the client easier to reason about, extend, and maintain.
5. Better Integration with Go Tooling
The API now works naturally with errors.Is, context cancellation, middleware, and structured logging without adapters.
6. Foundation for Long-Term Stability
These changes eliminate accumulated complexity and provide a clean base for future features without further breaking changes.
API Changes Before/After
Before (v1 - implicit errors, wrapped result)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
res := httpx.Get[User](client, "https://api.example.com/users/1")
if res.Err != nil {
log.Fatal(res.Err)
}
fmt.Println(res.Body.Name)Problems
- Error is hidden inside a wrapper
- Easy to forget to check
res.Err - Forces consumers to learn a custom response type
After (v2 - explicit, idiomatic Go)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
user, err := httpx.Get[User](client, "https://api.example.com/users/1")
if err != nil {
log.Fatal(err)
}
fmt.Println(user.Name)Improvements
- Errors are explicit and unavoidable
- Return values match standard Go expectations
- Cleaner, more readable call sites
Before (v1 - POST with response wrapper)
res := httpx.Post[CreateUser, User](client, "/users", CreateUser{Name: "Ana"})
if res.Err != nil {
log.Fatal(res.Err)
}
fmt.Println(res.Body)After (v2 - explicit input/output)
user, err := httpx.Post[CreateUser, User](client, "/users", CreateUser{Name: "Ana"})
if err != nil {
log.Fatal(err)
}
fmt.Println(user)Before (v1 - response wrapper access)
res := httpx.Get[User](client, "/users/1")
status := res.Response.StatusCodeAfter (v2 - explicit access via Do)
req := httpx.NewRequest("GET", "/users/1")
user, resp, err := httpx.Do[User](req)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.StatusCode)Summary
- No hidden error fields
- No wrapper structs
- Explicit, idiomatic Go APIs
- Easier to reason about and compose
This change makes the library safer, simpler, and more predictable without sacrificing power.
v1.1.0
What's Changed
- feat: browser profiles, fingerprinting by @cmilesdev in #1
- feat: add proxy/cookie/redirect + trace helpers + HEAD/OPTIONS by @cmilesdev in #2
Full Changelog: v1.0.0...v1.1.0
v1.0.0
Full Changelog: https://github.com/goforj/httpx/commits/v1.0.0