Skip to content

bearaujus/bhttp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BHTTP - Minimal HTTP Client Helper for Go (Automatic JSON Unwrapping, Simple Retries, Rate Limiting)

License Go Report Card

BHTTP is a lightweight Go library that wraps net/http. This library is able to validate expected status codes, retry on specific status codes, optionally rate limit requests, and decode JSON responses into a destination struct.

Installation

To install BHTTP, run:

go get github.com/bearaujus/bhttp

Import

import "github.com/bearaujus/bhttp"

Features

  • Validate response status codes (defaults to 200 OK).
  • Retry on specific response status codes (e.g., 429, 500, 502, 503, 504).
  • Optional rate limiting using golang.org/x/time/rate.
  • Decode JSON responses into a struct (DoAndUnwrap).
  • Helpful error messages including response body (pretty-printed if JSON).

Usage

1. Simple "send + unwrap"

type HttpBinGetResponse struct {
    URL     string            `json:"url"`
    Headers map[string]string `json:"headers"`
}

func main() {
    req, _ := http.NewRequest(http.MethodGet, "https://httpbin.org/get", nil)

    // BHTTP will automatically unmarshal the JSON response body into HttpBinGetResponse struct.
    resp, err := bhttp.DoAndUnwrap[HttpBinGetResponse](req)
    if err != nil {
        panic(err)
    }

    fmt.Printf("[%T] %+v\n", resp, resp)
}
[*main.HttpBinGetResponse] &{URL:https://httpbin.org/get Headers:map[Accept-Encoding:gzip Host:httpbin.org User-Agent:Go-http-client/2.0]}

2. Use Options to validate expected status codes.

func main() {
    req, _ := http.NewRequest(http.MethodGet, "https://httpbin.org/get", nil)

    opts := &bhttp.Options{
        // Only treat these status codes as success (defaults to 200 if omitted). 
        ExpectedStatusCodes: []int{http.StatusOK},
    }
    
    var out HttpBinGetResponse
    if err := bhttp.New().DoAndUnwrapWithOptions(req, &out, opts); err != nil {
        panic(err)
    }

    fmt.Printf("[%T] %+v\n", resp, resp)
}
[main.HttpBinGetResponse] {URL:https://httpbin.org/get Headers:map[Accept-Encoding:gzip Host:httpbin.org User-Agent:Go-http-client/2.0]}

3. Use Options + Retry to retry on specific status codes (e.g., 429 / 5xx).

func main() {
    // Using httpstat.us to simulate a retryable status.
    req, _ := http.NewRequest(http.MethodGet, "https://httpstat.us/503", nil)
    
    opts := &bhttp.Options{
        ExpectedStatusCodes: []int{http.StatusOK},
        Retry: &bhttp.RetryConfig{
            // Number of retries AFTER the first attempt (total tries = 1 + Attempts).
            Attempts: 2,
            
            // Retry only when the response status code matches one of these.
            RetryStatusCodes: []int{http.StatusTooManyRequests, http.StatusServiceUnavailable},
        },
    }
    
    // Note: On the final attempt, BHTTP will stop treating these as retryable so you get
    // a real error with the response body if it still fails.
    if err := bhttp.DoWithOptions(req, opts); err != nil {
        panic(err)
    }
}
panic: retries exhausted after 2 attempt(s): Get "https://httpstat.us/503": EOF

TODO

  • Add support for back-off retry, jitter & similar kind of components for retry mechanism

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

Minimal HTTP client helper for Go (Automatic JSON unwrapping, simple retries, rate limiting)

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages