h2non/gentleman — 1.1k★ on GitHub (Go). Plugin-driven, extensible HTTP client toolkit for Go
Snapshot summary built from the project's own GitHub metadata — there's no written TopGit review yet. The page will update automatically when a full review is published.
WHY NO REVIEW YET
TopGit writes full reviews for the most-starred, most-requested repositories. This page is a snapshot until then — see the READ ME tab for the original README in full.
Full-featured, plugin-driven, middleware-oriented toolkit to easily create rich, versatile and composable HTTP clients in Go.
gentleman embraces extensibility and composition principles in order to provide a flexible way to easily create featured HTTP client layers based on built-in or third-party plugins that you can register and reuse across HTTP clients.
As an example, you can easily provide retry policy capabilities or dynamic server discovery in your HTTP clients simply attaching the retry or consul plugins.
Take a look to the examples, list of supported plugins, HTTP entities or middleware layer to get started.
For testing purposes, see baloo, an utility library for expressive end-to-end HTTP API testing, built on top of gentleman toolkit. For HTTP mocking, see gentleman-mock, which uses gock under the hood for easy and expressive HTTP client request mocking.
Versions
v2 - Latest version. Stable. Recommended.
v1 - First version. Stable. Actively maintained.
Features
Plugin driven architecture.
Simple, expressive, fluent API.
Idiomatic built on top of net/http package.
Context-aware hierarchical middleware layer supporting all the HTTP life cycle.
Built-in multiplexer for easy composition capabilities.
Easy to extend via plugins/middleware.
Ability to easily intercept and modify HTTP traffic on-the-fly.
Convenient helpers and abstractions over Go's HTTP primitives.
URL template path params.
Built-in JSON, XML and multipart bodies serialization and parsing.
Easy to test via HTTP mocking (e.g: gentleman-mock).
Supports data passing across plugins/middleware via its built-in context.
Fits good while building domain-specific HTTP API clients.
Easy to hack.
Dependency free.
Installation
go get -u gopkg.in/h2non/gentleman.v2
Requirements
Go 1.9+
Plugins
Name
Docs
Status
Description
url
Easily declare URL, base URL and path values in HTTP requests
auth
Declare authorization headers in your requests
body
Easily define bodies based on JSON, XML, strings, buffers or streams
bodytype
Define body MIME type by alias
cookies
Declare and store HTTP cookies easily
compression
Helpers to define enable/disable HTTP compression
headers
Manage HTTP headers easily
multipart
Create multipart forms easily. Supports files and text fields
proxy
Configure HTTP proxy servers
query
Easily manage query params
redirect
Easily configure a custom redirect policy
timeout
Easily configure the HTTP timeouts (request, dial, TLS...)
transport
Define a custom HTTP transport easily
tls
Configure the TLS options used by the HTTP transport
retry
Provide retry policy capabilities to your HTTP clients
mock
Easy HTTP mocking using gock
consul
Consul based server discovery with configurable retry/backoff policy
Community plugins
Name
Docs
Status
Description
logger
Easily log requests and responses
Send a PR to add your plugin to the list.
Creating plugins
You can create your own plugins for a wide variety of purposes, such as server discovery, custom HTTP tranport, modify any request/response param, intercept traffic, authentication and so on.
Plugins are essentially a set of middleware function handlers for one or multiple HTTP life cycle phases exposing a concrete interface consumed by gentleman middleware layer.
For more details about plugins see the plugin package and examples.
Also you can take a look to a plugin implementation example.
HTTP entities
gentleman provides two HTTP high level entities: Client and Request.
Each of these entities provides a common API and are both middleware capable, giving you the ability to plug in custom components with own logic into any of them.
gentleman was designed to provide strong reusability capabilities.
This is mostly achieved via its built-in hierarchical, inheritance-based middleware layer.
The following list describes how inheritance hierarchy works and is used across gentleman's entities.
Client entity can inherit from other Client entity.
Request entity can inherit from a Client entity.
Client entity is mostly designed for reusability.
Client entity can create multiple Request entities who implicitly inherits from Client entity itself.
Request entity is designed to have specific HTTP request logic that is not typically reused.
Both Client and Request entities are full middleware capable interfaces.
Both Client and Request entities can be cloned in order to produce a copy but side-effects free new entity.
You can see an inheritance usage example here.
Middleware
gentleman is completely based on a hierarchical middleware layer based on plugins that executes one or multiple function handlers (aka plugin interface) providing a simple way to plug in intermediate custom logic in your HTTP client.
It supports multiple phases which represents the full HTTP request/response life cycle, giving you the ability to perform actions before and after an HTTP transaction happen, even intercepting and stopping it.
The middleware stack chain is executed in FIFO order designed for single thread model.
Plugins can support goroutines, but plugins implementors should prevent data race issues due to concurrency in multithreading programming.
For more implementation details about the middleware layer, see the middleware package and examples.
Middleware phases
Supported middleware phases triggered by gentleman HTTP dispatcher:
request - Executed before a request is sent over the network.
response - Executed when the client receives the response, even if it failed.
error - Executed in case that an error ocurrs, support both injected or native error.
stop - Executed in case that the request has been manually stopped via middleware (e.g: after interception).
intercept - Executed in case that the request has been intercepted before network dialing.
before dial - Executed before a request is sent over the network.
after dial - Executed after the request dialing was done and the response has been received.
Note that the middleware layer has been designed for easy extensibility, therefore new phases may be added in the future and/or the developer could be able to trigger custom middleware phases if needed.
Feel free to fill an issue to discuss this capabilities in detail.
API
See godoc reference for detailed API documentation.
Subpackages
plugin - godoc - Plugin layer for gentleman.
mux - godoc - HTTP client multiplexer with built-in matchers.
middleware - godoc - Middleware layer used by gentleman.
context - godoc - HTTP context implementation for gentleman's middleware.
utils - godoc - HTTP utilities internally used.
Examples
See examples directory for featured examples.
Simple request
package main
import (
"fmt"
"gopkg.in/h2non/gentleman.v2"
)
func main() {
// Create a new client
cli := gentleman.New()
// Define base URL
cli.URL("http://httpbin.org")
// Create a new request based on the current client
req := cli.Request()
// Define the URL path at request level
req.Path("/headers")
// Set a new header field
req.SetHeader("Client", "gentleman")
// Perform the request
res, err := req.Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
}
if !res.Ok {
fmt.Printf("Invalid server response: %d\n", res.StatusCode)
return
}
// Reads the whole body and returns it as string
fmt.Printf("Body: %s", res.String())
}
Send JSON body
package main
import (
"fmt"
"gopkg.in/h2non/gentleman.v2"
"gopkg.in/h2non/gentleman.v2/plugins/body"
)
func main() {
// Create a new client
cli := gentleman.New()
// Define the Base URL
cli.URL("http://httpbin.org/post")
// Create a new request based on the current client
req := cli.Request()
// Method to be used
req.Method("POST")
// Define the JSON payload via body plugin
data := map[string]string{"foo": "bar"}
req.Use(body.JSON(data))
// Perform the request
res, err := req.Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
}
if !res.Ok {
fmt.Printf("Invalid server response: %d\n", res.StatusCode)
return
}
fmt.Printf("Status: %d\n", res.StatusCode)
fmt.Printf("Body: %s", res.String())
}
Composition via multiplexer
package main
import (
"fmt"
"gopkg.in/h2non/gentleman.v2"
"gopkg.in/h2non/gentleman.v2/mux"
"gopkg.in/h2non/gentleman.v2/plugins/url"
)
func main() {
// Create a new client
cli := gentleman.New()
// Define the server url (must be first)
cli.Use(url.URL("http://httpbin.org"))
// Create a new multiplexer based on multiple matchers
mx := mux.If(mux.Method("GET"), mux.Host("httpbin.org"))
// Attach a custom plugin on the multiplexer that will be executed if the matchers passes
mx.Use(url.Path("/headers"))
// Attach the multiplexer on the main client
cli.Use(mx)
// Perform the request
res, err := cli.Request().Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
}
if !res.Ok {
fmt.Printf("Invalid server response: %d\n", res.StatusCode)
return
}
fmt.Printf("Status: %d\n", res.StatusCode)
fmt.Printf("Body: %s", res.String())
}
The most recent commit recorded on h2non/gentleman was 2.7 years ago, based on the GitHub push timestamp. The repository has 58 forks — one of the better signals of community interest.
How many stars does h2non/gentleman have?
h2non/gentleman has 1.1k GitHub stars — refresh the page for the live number, or check github.com/h2non/gentleman. TopGit mirrors GitHub's count but does not claim minute-by-minute accuracy.
Is h2non/gentleman open source?
Yes — h2non/gentleman ships under the MIT license, which makes its source code freely readable (and, depending on license terms, forkable and reusable). Source: github.com/h2non/gentleman.
What else is in the Backend space?
h2non/gentleman is tracked by TopGit under the Backend category, alongside 10 GitHub-tagged topics. Trending and Topics pages list peer repositories of comparable stars and language.
What is h2non/gentleman?
h2non/gentleman (h2non/gentleman) is a Go project on GitHub. From the project's own README: Plugin-driven, extensible HTTP client toolkit for Go
What language is h2non/gentleman written in?
h2non/gentleman is written primarily in Go. GitHub's language field is based on the largest share of bytes in the default branch.
What license does h2non/gentleman use?
h2non/gentleman is released under the MIT license. Always verify the LICENSE file directly on GitHub for the authoritative terms — license strings can be edited out of sync with a project's actual stance.
Where do I read more about h2non/gentleman?
This TopGit page is a snapshot — the READ ME tab shows the project's own README content (links stripped, images preserved). The GitHub repository at github.com/h2non/gentleman is the definitive source.
Read full README in the tab above.
Is gentleman worth your time?
ChatGPT, Claude and Perplexity can all read this page. Ask one of them what it makes of gentleman.