Make API Calls in Go Without the Pain
Introducing httpc — A Simple, Fluent HTTP Client Wrapper for Go
If you’ve ever worked with APIs in Go, you’ve probably felt the same thing most Go developers do:
“Why does something as simple as calling an API and parsing JSON feel so verbose?”
Go’s standard net/http, encoding/json, and related packages are solid — but when you combine them for real-world API clients, the code often gets repetitive, boilerplate-heavy, and harder to maintain than it needs to be.
To fix that, I built httpc — a small wrapper over the default Go HTTP client that makes everyday API tasks simple, expressive, and ergonomic while staying close to Go’s philosophy. ([Go Packages][1])
Why We Need Something Better
With the standard library, even a simple JSON API call looks like this:
- create a request
- set headers
- send the request
- read the response
- close the body
- unmarshal JSON
- handle errors
…and that’s before you add timeouts, retries, auth, or anything else.
This is great for building blocks — but not great when you just want to call an API and get things done.
httpc hides most of that boilerplate so you can focus on the logic your app actually cares about.
What httpc Gives You
httpc is designed around a few simple principles:
✔ Fluent & Chainable API
✔ Sensible defaults out-of-the-box
✔ Simple for beginners, powerful for pros
✔ Support for retries, timeouts, rate limiting, circuit breakers
✔ Easy JSON encoding/decoding
✔ Middleware support
✔ Testing tools like mock servers ([Go Packages][1])
Let’s look at how this changes your day-to-day code.
Quick Start — Making Requests
Simple GET
Instead of all the typical setup, you can write:
resp, err := httpc.New().
Get("https://api.example.com/users").
Do()
if err != nil {
log.Fatal(err)
}
defer resp.Close()
fmt.Println(resp.Status())
That’s it. No manual request building. No manual body closing. ([Go Packages][1])
POST with JSON
Sending a struct as JSON and making a POST is literally just:
user := User{Name: "John", Email: "john@example.com"}
resp, err := httpc.New().
Post("https://api.example.com/users").
JSON(user).
Do()
No json.Marshal first. No setting "Content-Type" manually. ([Go Packages][1])
Get JSON Directly as a Struct
Want to decode the response into a struct in one step?
var users []User
err := httpc.New().
Get("https://api.example.com/users").
DecodeJSON(&users)
The response is parsed and unmarshaled for you. ([Go Packages][1])
Important Features That Save Time
Headers & Query Parameters
client := httpc.New().
WithBaseURL("https://api.example.com").
WithHeader("Accept", "application/json")
resp, _ := client.Get("/users").
Query("page", "1").
Query("limit", "10").
Do()
Note how WithBaseURL makes relative URLs easy. ([Go Packages][1])
Timeouts & Custom Clients
You can set timeouts at the client or per-request level:
client := httpc.New().WithTimeout(30 * time.Second)
resp, _ := client.Get("/slow-endpoint").
Timeout(60 * time.Second).
Do()
No more juggling contexts manually unless you want to. ([Go Packages][1])
Resilience: Retries, Circuit Breakers, Rate Limiting
If you care about real-world API reliability:
client := httpc.New().
WithRetry(3, time.Second).
WithCircuitBreaker(5, time.Minute).
WithRateLimiter(10)
You get automatic retries with exponential backoff, circuit breakers, and rate control. ([Go Packages][1])
Testing Made Easy
Testing API clients can be hard. httpc includes a mock server utility so you can write tests like:
server := mock.NewServer()
defer server.Close()
server.OnGet("/users/1").
Status(200).
JSON(User{ID: 1, Name: "John"}).
Reply()
client := httpc.New().WithBaseURL(server.URL())
var user User
err := client.Get("/users/1").DecodeJSON(&user)
No external APIs needed — just fast, reliable tests. ([Go Packages][2])
Final Thoughts
Go’s standard library is powerful, but it’s also minimal by design. That means for anything beyond trivial use, you end up writing a lot of repetitive code.
httpc keeps what’s good about Go’s ecosystem — simplicity, clarity, composability — while reducing the boilerplate around common HTTP and JSON tasks.
If you build clients, microservices, or backend integrations in Go, this tool can save you time and make your code easier to read and maintain.
👉 Check out the docs: https://pkg.go.dev/github.com/jnaneshd/httpc
Top comments (0)