{"id":13413644,"url":"https://github.com/h2non/gentleman","last_synced_at":"2025-05-15T11:08:23.928Z","repository":{"id":40634666,"uuid":"52232784","full_name":"h2non/gentleman","owner":"h2non","description":"Plugin-driven, extensible HTTP client toolkit for Go","archived":false,"fork":false,"pushed_at":"2023-12-17T15:53:50.000Z","size":262,"stargazers_count":1104,"open_issues_count":27,"forks_count":54,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-05-08T04:36:49.257Z","etag":null,"topics":["client","consul","golang","http","http-client","middleware","modular","pluggable","retry","sdk"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/h2non/gentleman?tab=doc","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/h2non.png","metadata":{"files":{"readme":"README.md","changelog":"History.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2016-02-21T23:00:24.000Z","updated_at":"2025-05-03T21:16:48.000Z","dependencies_parsed_at":"2024-02-01T17:47:59.731Z","dependency_job_id":null,"html_url":"https://github.com/h2non/gentleman","commit_stats":{"total_commits":194,"total_committers":13,"mean_commits":"14.923076923076923","dds":0.08247422680412375,"last_synced_commit":"94efe30d594b47706eb53a60938632df2cf8d934"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2non%2Fgentleman","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2non%2Fgentleman/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2non%2Fgentleman/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2non%2Fgentleman/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/h2non","download_url":"https://codeload.github.com/h2non/gentleman/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253239425,"owners_count":21876459,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["client","consul","golang","http","http-client","middleware","modular","pluggable","retry","sdk"],"created_at":"2024-07-30T20:01:45.294Z","updated_at":"2025-05-15T11:08:23.909Z","avatar_url":"https://github.com/h2non.png","language":"Go","funding_links":[],"categories":["Networking","Utilities","开源类库","Go","网络","Open source library","网络相关库","實用工具","HTTP Clients","工具库","实用工具"],"sub_categories":["HTTP Clients","Advanced Console UIs","HTTP","HTTP客户端","HTTP Print Test","Http Client","高級控制台界面","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e","交流","高级控制台界面"],"readme":"# gentleman [![GitHub release](https://img.shields.io/badge/version-2.0.5-orange.svg?style=flat)](https://github.com/h2non/gentleman/releases) [![GoDoc](https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg)](https://godoc.org/gopkg.in/h2non/gentleman.v2) [![Coverage Status](https://coveralls.io/repos/github/h2non/gentleman/badge.svg?branch=master)](https://coveralls.io/github/h2non/gentleman?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/h2non/gentleman)](https://goreportcard.com/report/github.com/h2non/gentleman) [![Go Version](https://img.shields.io/badge/go-v2.0+-green.svg?style=flat)](https://github.com/h2non/gentleman)\n\nFull-featured, plugin-driven, middleware-oriented toolkit to easily create rich, versatile and composable HTTP clients in [Go](http://golang.org).\n\n\u003cimg src=\"http://s10.postimg.org/5e31ox1ft/gentleman.png\" align=\"right\" height=\"260\" /\u003e\n\ngentleman 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.\n\nAs an example, you can easily provide retry policy capabilities or dynamic server discovery in your HTTP clients simply attaching the [retry](https://github.com/h2non/gentleman-retry) or [consul](https://github.com/h2non/gentleman-consul) plugins.\n\nTake a look to the [examples](#examples), list of [supported plugins](#plugins), [HTTP entities](#http-entities) or [middleware layer](#middleware) to get started.\n\nFor testing purposes, see [baloo](https://github.com/h2non/baloo), an utility library for expressive end-to-end HTTP API testing, built on top of `gentleman` toolkit. For HTTP mocking, see [gentleman-mock](https://github.com/h2non/gentleman-mock), which uses [gock](https://github.com/h2non/gock) under the hood for easy and expressive HTTP client request mocking.\n\n## Versions\n\n- [v2](https://github.com/h2non/gentleman/) - Latest version. Stable. Recommended.\n- [v1](https://github.com/h2non/gentleman/tree/v1) - First version. Stable. Actively maintained.\n\n## Features\n\n- Plugin driven architecture.\n- Simple, expressive, fluent API.\n- Idiomatic built on top of `net/http` package.\n- Context-aware hierarchical middleware layer supporting all the HTTP life cycle.\n- Built-in multiplexer for easy composition capabilities.\n- Easy to extend via plugins/middleware.\n- Ability to easily intercept and modify HTTP traffic on-the-fly.\n- Convenient helpers and abstractions over Go's HTTP primitives.\n- URL template path params.\n- Built-in JSON, XML and multipart bodies serialization and parsing.\n- Easy to test via HTTP mocking (e.g: [gentleman-mock](https://github.com/h2non/gentleman-mock)).\n- Supports data passing across plugins/middleware via its built-in context.\n- Fits good while building domain-specific HTTP API clients.\n- Easy to hack.\n- Dependency free.\n\n## Installation\n\n```bash\ngo get -u gopkg.in/h2non/gentleman.v2\n```\n\n## Requirements\n\n- Go 1.9+\n\n## Plugins\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eName\u003c/th\u003e\n    \u003cth\u003eDocs\u003c/th\u003e\n    \u003cth\u003eStatus\u003c/th\u003e\n    \u003cth\u003eDescription\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/url\"\u003eurl\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/url\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eEasily declare URL, base URL and path values in HTTP requests\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/auth\"\u003eauth\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/auth\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eDeclare authorization headers in your requests\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/body\"\u003ebody\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/body\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eEasily define bodies based on JSON, XML, strings, buffers or streams\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/bodytype\"\u003ebodytype\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/bodytype\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eDefine body MIME type by alias\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/cookies\"\u003ecookies\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/cookies\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eDeclare and store HTTP cookies easily\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/compression\"\u003ecompression\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/compression\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eHelpers to define enable/disable HTTP compression\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/headers\"\u003eheaders\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/headers\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eManage HTTP headers easily\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/multipart\"\u003emultipart\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/multipart\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eCreate multipart forms easily. Supports files and text fields\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/proxy\"\u003eproxy\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/proxy\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eConfigure HTTP proxy servers\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/query\"\u003equery\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/query\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eEasily manage query params\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/redirect\"\u003eredirect\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/redirect\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eEasily configure a custom redirect policy\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/timeout\"\u003etimeout\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/timeout\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eEasily configure the HTTP timeouts (request, dial, TLS...)\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/transport\"\u003etransport\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/transport\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eDefine a custom HTTP transport easily\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman/tree/master/plugins/tls\"\u003etls\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2/plugins/tls\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eConfigure the TLS options used by the HTTP transport\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman-retry\"\u003eretry\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2-retry\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2-retry?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman-retry\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman-retry.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eProvide retry policy capabilities to your HTTP clients\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman-mock\"\u003emock\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2-mock\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2-mock?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman-mock\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman-mock.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eEasy HTTP mocking using \u003ca href=\"https://github.com/h2non/gock\"\u003egock\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/h2non/gentleman-consul\"\u003econsul\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/gopkg.in/h2non/gentleman.v2-consul\"\u003e\n        \u003cimg src=\"https://godoc.org/gopkg.in/h2non/gentleman.v2-consul?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/h2non/gentleman-consul\"\u003e\u003cimg src=\"https://travis-ci.org/h2non/gentleman-consul.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://www.consul.io\"\u003eConsul\u003c/a\u003e based server discovery with configurable retry/backoff policy\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n### Community plugins\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eName\u003c/th\u003e\n    \u003cth\u003eDocs\u003c/th\u003e\n    \u003cth\u003eStatus\u003c/th\u003e\n    \u003cth\u003eDescription\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ca href=\"https://github.com/izumin5210/gentleman-logger\"\u003elogger\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://godoc.org/github.com/izumin5210/gentleman-logger\"\u003e\n        \u003cimg src=\"https://godoc.org/github.com/izumin5210/gentleman-logger?status.svg\" /\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\u003ca href=\"https://travis-ci.org/izumin5210/gentleman-logger\"\u003e\u003cimg src=\"https://travis-ci.org/izumin5210/gentleman-logger.png\" /\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd\u003eEasily log requests and responses\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n[Send](https://github.com/h2non/gentleman/pull/new/master) a PR to add your plugin to the list.\n\n### Creating plugins\n\nYou 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.\n\nPlugins are essentially a set of middleware function handlers for one or multiple HTTP life cycle phases exposing [a concrete interface](https://github.com/h2non/gentleman/blob/755d55eef0bd26ae6b4ee19fe59001db2c46a51b/plugin/plugin.go#L16-L35) consumed by gentleman middleware layer.\n\nFor more details about plugins see the [plugin](https://github.com/h2non/gentleman/tree/master/plugin) package and [examples](https://github.com/h2non/gentleman/tree/master/_examples/plugin).\n\nAlso you can take a look to a plugin [implementation example](https://github.com/h2non/gentleman/blob/master/_examples/plugin/plugin.go).\n\n## HTTP entities\n\n`gentleman` provides two HTTP high level entities: `Client` and `Request`.\n\nEach 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.\n\n`gentleman` was designed to provide strong reusability capabilities.\nThis is mostly achieved via its built-in hierarchical, inheritance-based middleware layer.\n\nThe following list describes how inheritance hierarchy works and is used across gentleman's entities.\n\n- `Client` entity can inherit from other `Client` entity.\n- `Request` entity can inherit from a `Client` entity.\n- `Client` entity is mostly designed for reusability.\n- `Client` entity can create multiple `Request` entities who implicitly inherits from `Client` entity itself.\n- `Request` entity is designed to have specific HTTP request logic that is not typically reused.\n- Both `Client` and `Request` entities are full middleware capable interfaces.\n- Both `Client` and  `Request` entities can be cloned in order to produce a copy but side-effects free new entity.\n\nYou can see an inheritance usage example [here](https://github.com/h2non/gentleman/blob/master/_examples/inheritance/inheritance.go).\n\n## Middleware\n\ngentleman 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.\n\nIt 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.\n\nThe middleware stack chain is executed in FIFO order designed for single thread model.\nPlugins can support goroutines, but plugins implementors should prevent data race issues due to concurrency in multithreading programming.\n\nFor more implementation details about the middleware layer, see the [middleware](https://github.com/h2non/gentleman/tree/master/middleware) package and [examples](https://github.com/h2non/gentleman/tree/master/_examples/middleware).\n\n#### Middleware phases\n\nSupported middleware phases triggered by gentleman HTTP dispatcher:\n\n- **request** - Executed before a request is sent over the network.\n- **response** - Executed when the client receives the response, even if it failed.\n- **error** - Executed in case that an error ocurrs, support both injected or native error.\n- **stop** - Executed in case that the request has been manually stopped via middleware (e.g: after interception).\n- **intercept** - Executed in case that the request has been intercepted before network dialing.\n- **before dial** - Executed before a request is sent over the network.\n- **after dial** - Executed after the request dialing was done and the response has been received.\n\nNote 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.\n\nFeel free to fill an issue to discuss this capabilities in detail.\n\n## API\n\nSee [godoc reference](https://godoc.org/gopkg.in/h2non/gentleman.v2) for detailed API documentation.\n\n#### Subpackages\n\n- [plugin](https://github.com/h2non/gentleman/tree/master/plugin) - [godoc](https://godoc.org/gopkg.in/h2non/gentleman.v2/plugin) - Plugin layer for gentleman.\n- [mux](https://github.com/h2non/gentleman/tree/master/mux) - [godoc](https://godoc.org/gopkg.in/h2non/gentleman.v2/mux) - HTTP client multiplexer with built-in matchers.\n- [middleware](https://github.com/h2non/gentleman/tree/master/middleware) - [godoc](https://godoc.org/gopkg.in/h2non/gentleman.v2/middleware) - Middleware layer used by gentleman.\n- [context](https://github.com/h2non/gentleman/tree/master/context) - [godoc](https://godoc.org/gopkg.in/h2non/gentleman.v2/context) - HTTP context implementation for gentleman's middleware.\n- [utils](https://github.com/h2non/gentleman/tree/master/utils) - [godoc](https://godoc.org/gopkg.in/h2non/gentleman.v2/utils) - HTTP utilities internally used.\n\n## Examples\n\nSee [examples](https://github.com/h2non/gentleman/blob/master/_examples) directory for featured examples.\n\n#### Simple request\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n\n  \"gopkg.in/h2non/gentleman.v2\"\n)\n\nfunc main() {\n  // Create a new client\n  cli := gentleman.New()\n\n  // Define base URL\n  cli.URL(\"http://httpbin.org\")\n\n  // Create a new request based on the current client\n  req := cli.Request()\n\n  // Define the URL path at request level\n  req.Path(\"/headers\")\n\n  // Set a new header field\n  req.SetHeader(\"Client\", \"gentleman\")\n\n  // Perform the request\n  res, err := req.Send()\n  if err != nil {\n    fmt.Printf(\"Request error: %s\\n\", err)\n    return\n  }\n  if !res.Ok {\n    fmt.Printf(\"Invalid server response: %d\\n\", res.StatusCode)\n    return\n  }\n\n  // Reads the whole body and returns it as string\n  fmt.Printf(\"Body: %s\", res.String())\n}\n```\n\n#### Send JSON body\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n\n  \"gopkg.in/h2non/gentleman.v2\"\n  \"gopkg.in/h2non/gentleman.v2/plugins/body\"\n)\n\nfunc main() {\n  // Create a new client\n  cli := gentleman.New()\n\n  // Define the Base URL\n  cli.URL(\"http://httpbin.org/post\")\n\n  // Create a new request based on the current client\n  req := cli.Request()\n\n  // Method to be used\n  req.Method(\"POST\")\n\n  // Define the JSON payload via body plugin\n  data := map[string]string{\"foo\": \"bar\"}\n  req.Use(body.JSON(data))\n\n  // Perform the request\n  res, err := req.Send()\n  if err != nil {\n    fmt.Printf(\"Request error: %s\\n\", err)\n    return\n  }\n  if !res.Ok {\n    fmt.Printf(\"Invalid server response: %d\\n\", res.StatusCode)\n    return\n  }\n\n  fmt.Printf(\"Status: %d\\n\", res.StatusCode)\n  fmt.Printf(\"Body: %s\", res.String())\n}\n```\n\n#### Composition via multiplexer\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n\n  \"gopkg.in/h2non/gentleman.v2\"\n  \"gopkg.in/h2non/gentleman.v2/mux\"\n  \"gopkg.in/h2non/gentleman.v2/plugins/url\"\n)\n\nfunc main() {\n  // Create a new client\n  cli := gentleman.New()\n\n  // Define the server url (must be first)\n  cli.Use(url.URL(\"http://httpbin.org\"))\n\n  // Create a new multiplexer based on multiple matchers\n  mx := mux.If(mux.Method(\"GET\"), mux.Host(\"httpbin.org\"))\n\n  // Attach a custom plugin on the multiplexer that will be executed if the matchers passes\n  mx.Use(url.Path(\"/headers\"))\n\n  // Attach the multiplexer on the main client\n  cli.Use(mx)\n\n  // Perform the request\n  res, err := cli.Request().Send()\n  if err != nil {\n    fmt.Printf(\"Request error: %s\\n\", err)\n    return\n  }\n  if !res.Ok {\n    fmt.Printf(\"Invalid server response: %d\\n\", res.StatusCode)\n    return\n  }\n\n  fmt.Printf(\"Status: %d\\n\", res.StatusCode)\n  fmt.Printf(\"Body: %s\", res.String())\n}\n```\n\n## License\n\nMIT - Tomas Aparicio\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh2non%2Fgentleman","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fh2non%2Fgentleman","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh2non%2Fgentleman/lists"}