An HTTP networking client written in go.
GoHTTP
is built on top of the net/http
package and is designed to make integrating with JSON APIs from golang
applications simple and easy.
GoHTTP
offer two distinct, out-of-the-box features that separate it from other networking clients.
- Rate Limiting - Most public APIs are going to have some form of rate limiting requirements. GoHTTP leverages Funnel to make conforming to these rate limits trivial.
- Retry w/ Exponential BackOff - Systems can fail or error in the wild and applications should be resilient.
GoHTTP
makes it easy for applications to specify the HTTP status codes that should result in a retry.GoHTTP
retries using an exponential backoff algorithm powered by Exponential Backoff.
GoHTTP
also provides syntactic sugar on top of the net/http
package that makes networking easier from go applications (i.e. applications can use maps for request and response JSON bodies).
- HTTP verbs supported Get, Put, Post, Patch, Delete
- Rich object models for requests and responses
- JSON and Form Data requests
- Header and method constants
- Retry with exponential backoff
- Rate limiting backed by Redis
- Response JSON parsing
- JSON pretty printing
- Full documentation
- Comprehensive Unit Test Coverage
$ go get github.com/meshhq/gohttp
import "github.com/meshhq/gohttp"
GET request
request := gohttp.Request{Method: gohttp.GET}
client := &gohttp.NewClient("api.google.com", nil)
response, err := client.Execute(request)
POST request
request := &gohttp.Request{
Method: gohttp.POST,
URL: "/users",
Body: map[string]interface{}{"first_name": "Kevin"},
}
client := gohttp.NewClient("api.google.com", nil)
response, err := client.Execute(request)
All requests are executed with a Client
. Client
objects can hold global parameters such as a baseURL
or a set of headers
. Global parameters will be applied to each request that is executed by the Client
.
baseURL := "api.google.com"
headers := map[string]string{gohttp.Accept : "application/json"}
client := gohttp.NewClient(baseURL, headers)
gohttp
provides a Request
object which makes building HTTP request simple and readable. The URL
parameter of a request is relative to the baseURL
parameter of a the Client
that executes it.
request := &gohttp.Request{
Method: gohttp.POST,
URL: "/users",
Body: map[string]interface{}{"first_name": "Kevin"},
}
response, err := client.Execute(request)
A call to the Execute
method on a Client
object will return a Response
object and an error
that describes any failure that occurred.
response, err := client.Execute(request)
if err != nil {
return err
}
fmt.Printf("Response: %v", response)
The Response
object contains parsed information about the outcome of an HTTP request.
fmt.Printf("Code: %v\n", response.Code) // int containing the response code.
fmt.Printf("Body: %v\n", response.Body) // interface{} containing the parsed response body.
fmt.Printf("Request: %v\n", response.Request) // `gohttp.Request` object which is a pointer to the original request.
Applications can also pretty print response objects via the GoHTTP
convenience method PrettyPrint
. This method is very useful when debugging http requests.
gohttp.PrettyPrint(response)
Example PrettyPrint
output.
{
"Code": 201,
"Data": "",
"Body": null,
"Error": null,
"Request": {
"Method": "POST",
"Header": {},
"URL": "/test",
"Params": null,
"Body": {
"name": "test"
},
"Form": null
}
}
GoHTTP
implements sophisticated retry logic with exponential backoff. Applications can configure the status codes for which an application should retry a request via the RetryableStatusCodes
parameter on a Client
object.
client.RetryableStatusCodes = []int{403} // Rate Limit Exceeded
Underneath the hood, GoHTTP
leverages the Exponential Backoff package for building and executing the backoff algorithm. GoHTTP
supplies a default backoff algorithm implementation, but applications can supply their own via the Backoff
parameter on a Client
object.
var backOff := func() error {
// Algorithm configuration
}
client.Backoff = backOff
GoHTTP provides robust, out of the box rate limiting support. This makes it very easy to conform with rate limiting policies published by APIs. Underneath the hood, GoHTTP
leverages Funnel, a distributed rate limiter backed by redis.
Applications can configure their rate limiting policy by supplying a LimitInfo
object to a Client
object.
token
- A unique token upon which requests are limited. For example, if all requests to the gmail API need to be limited, applications could use the token "gmail".MaxRequests
- The maximum number of requests that can take place within a given time interval.TimeInterval
- The time interval in (milliseconds) to which theMaxRequests
parameter applies.
info := &RateLimitInfo{
Token: "unique-token",
MaxRequests: 10,
TimeInterval: 1000,
}
client.SetRateLimiterInfo(info)
Applications can concurrently execute requests to the same client from as many goroutines
as they wish. The Client
will handle queuing requests with redis, and ensure that the rate limit is not breached and all requests are executed.
PRs are welcome, but will be rejected unless test coverage is updated