Skip to content

Releases: goforj/httpx

v2.0.0

29 Dec 07:32

Choose a tag to compare

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

After (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

29 Dec 03:57
1698ed9

Choose a tag to compare

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

26 Dec 23:10

Choose a tag to compare