DEV Community

Jnanesh D
Jnanesh D

Posted on

Httpc - A much needed wrapper

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())
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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)