Library / SDK
go-resty/resty avatar
go-resty/resty

go-resty/resty: a Go HTTP client that bundles retries, circuit breaking and SSE

Simple HTTP, REST, and SSE client library for Go

11,815 stars810 forksGoMIT

At a glance

What is it?
Resty is an MIT-licensed Go client library that wraps net/http with retry, circuit breaker, load balancing and server-sent events, and the v3 line is still at release candidate stage. Here is what the repository actually contains and where the abstraction stops paying for itself.
Who is it for?
Adopt Resty if you are writing Go services that call several HTTP APIs and you want retry, circuit breaker and SSE handling without assembling them yourself, and if you can tolerate tracking a v3 release candidate. Stay with net/http and small helper functions if your client is one endpoint with no retry policy, or if you need streaming semantics you control byte by byte, since stream.go and sse.go sit on top of the standard response body.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Resty is for, and who ends up using it

The standard library gives Go developers net/http, which is a correct HTTP implementation and not a client framework. Anything beyond a single request means you write the retry loop, decide what counts as a retryable status, attach headers consistently, and handle the case where a dependency is failing. Resty exists to hold that code once. The repository description is "Simple HTTP, REST, and SSE client library for Go", and the top-level files map to those concerns directly: retry.go, circuit_breaker.go, load_balancer.go, rate_limiter.go, hedging.go, redirect.go, digest.go, middleware.go, trace.go, sse.go and stream.go.

The audience is Go service developers who talk to third-party or internal HTTP APIs and want policy applied uniformly. The build constraint is explicit: the README says to use go1.23 and above, and go.mod declares go 1.23.0. The only external dependency listed in go.mod is golang.org/x/net. That is a small surface for a library that covers this much ground, and it matters if you are the person who has to justify every entry in a dependency review.

It is a library, not a server or a CLI. There is nothing to run in production except your own binary.

How the request pipeline is assembled

The architecture is a client object that owns configuration, and a request object that carries per-call state. client.go and request.go are the two central files, with response.go holding the result. Middleware runs as a chain: middleware.go defines the hook points, and the repository separates middleware_test.go from client_test.go, which suggests middleware is a first-class extension point rather than an afterthought.

The policy features are separate units that plug into that pipeline rather than being baked into the transport. circuit_breaker.go, rate_limiter.go, hedging.go, retry.go and load_balancer.go each have their own source file and their own test file. That layout is the strongest signal in the repository about how the author expects the library to be used: you opt into the policies you need, and each one is independently testable.

Transport-level concerns are also split out. transport_dial.go and transport_dial_wasm.go are separate files, so the dial path has a WebAssembly variant. trace.go handles request tracing, and curl.go generates a curl command representation of a request. That last one is a debugging affordance: when a request fails in a way you cannot reproduce, having the library emit an equivalent curl invocation is more useful than a stack trace.

Server-sent events get their own file, sse.go, and streaming gets stream.go. Both are distinct from the ordinary request path, which is the right call: SSE is a long-lived response with a specific framing, and folding it into the normal response handling would complicate both.

Installing Resty and making a first request

The README does not contain installation steps. It points to https://resty.dev and to godoc, states the minimum Go version, and describes versioning. The versioning section is where the module path comes from: Resty v3 provides the Go vanity URL resty.dev/v3, and go.mod confirms the module declaration as resty.dev/v3. So the import path is the vanity URL, not the GitHub path. If you have used v2, the README notes that v2 lived at github.com/go-resty/resty/v2, and v1 used gopkg.in. The path changed across major versions.

Add the module with the vanity path. The README does not print this command, but it follows from the module declaration in go.mod, which is the module line shown below:

bash
go get resty.dev/v3

The module declaration itself, quoted from go.mod, is what your build resolves against:

code
module resty.dev/v3

From there, configuration is applied on the client and the call is issued from a request object. The README does not document any of the setter names or show a code sample, so treat the godoc entry for resty.dev/v3 as the source of truth rather than copying a snippet from a blog post. The same applies to the policy features: retry.go, circuit_breaker.go and load_balancer.go exist as files, but the README documents none of their configuration keys. You will be reading godoc either way.

One practical note on the release line. The most recent release is v3.0.0-rc.4, dated 2026-09-06, preceded by rc.3 in July and rc.2 in June. That is a release candidate, not a final v3.0.0. If your policy forbids release candidates in production, the import path resty.dev/v3 is not yet the one you want.

The v3 release candidate is the real adoption risk

The repository is not archived, and the last push was on 2026-09-21, so this is not an abandoned project. The limitation is elsewhere: v3 has not shipped a stable release. The release list shows v3.0.0-rc.4, v3.0.0-rc.3 and v3.0.0-rc.2, and nothing after them. Anyone adopting resty.dev/v3 is adopting a pre-release API.

What that means in practice is that the vanity import path and the API surface can still move before v3.0.0 lands. The README's versioning section is careful about paths and silent about API stability guarantees for the candidate line. There is no compatibility promise printed for rc to final.

A second limitation is documentation placement. The README is short by design and delegates everything to resty.dev and godoc. That is fine for a library with a well-known API, and less fine for one where the interesting parts are retry policy, circuit breaker thresholds and load balancer selection. Those files exist; the README does not describe them. If you are evaluating Resty from the repository alone, you will not learn what the circuit breaker counts, how the load balancer picks a target, or what the retry defaults are. You have to leave the repository to find out.

A third point, which is a design trade-off rather than a defect: bundling retry, circuit breaking, hedging, rate limiting and load balancing into one client means one dependency carries all of them. If you only want retry, you are still importing a package whose other files exist in your build graph. The go.mod dependency list is short, so the transitive cost is low, but the API surface you agree to is not.

Resty compared with plain net/http and with the OpenTelemetry wrapper

The realistic alternative is not another client library. It is net/http plus a thin wrapper you write and own. The difference in approach is where the policy lives. With net/http, retry is a loop you write, the circuit breaker is a struct you maintain, and the load balancer is a decision you make at the transport or dialer level. You get exactly the semantics you specified, and you get to debug them. With Resty, those policies arrive as files in someone else's package: retry.go, circuit_breaker.go, load_balancer.go, hedging.go, rate_limiter.go. You configure them instead of writing them, and in exchange you accept their defaults and their bugs.

That trade is worth taking when you have several outbound APIs and want one consistent policy. It is a poor trade when you have one endpoint and a two-line retry rule, because you have added a dependency and a configuration vocabulary to replace code you already understood.

There is a second comparison worth making, on the observability side. Resty ships trace.go, which means request tracing is part of the library rather than delegated to an external instrumentation package. If you already wrap your HTTP client with an OpenTelemetry transport, you should check how Resty's tracing interacts with it before assuming the two compose cleanly. The README does not address this, and the repository does not contain an OpenTelemetry integration file.

On the SSE side, the alternative to sse.go is hand-parsing an event stream over a response body you read yourself. That is not hard, but it is fiddly, and the framing rules are easy to get subtly wrong. This is the one area where Resty's file layout suggests a genuine convenience rather than a thin wrapper over something you would write anyway.

Maintenance, upgrade cost and the MIT licence

The repository is under the MIT licence, per the LICENSE file and the README's license section. MIT is permissive: it allows commercial and closed-source use, and it requires that the copyright notice and permission notice be included. That last part is the practical obligation, and it is the kind of thing your dependency tooling usually handles. The README also notes that the documentation repository and website are under Apache-2.0, which is a separate licence from the library itself. Do not assume the site's licence covers the code you import.

Upgrade cost is dominated by the major-version path changes. The README lays out the history: v1 used gopkg.in, v2 moved to github.com/go-resty/resty/v2, and v3 uses the vanity URL resty.dev/v3. Moving from v2 to v3 is therefore an import path change plus whatever API changes the release notes describe, and the release notes are the place to check because the README does not enumerate them.

Within the v3 line, the current position is rc.4. The gap between rc.2 in June, rc.3 in July and rc.4 in September suggests active iteration on the candidate, and it also means the API is still settling. Budget for a review pass when v3.0.0 final arrives.

Contribution expectations are stated plainly in the README: pull requests must include test cases with patch coverage of 100 percent. That is a high bar for outside contributors, and it is worth knowing if you were planning to patch a policy file yourself rather than wait for a release.

Editorial conclusion

Adopt Resty if you are writing Go services that call several HTTP APIs and you want retry, circuit breaker and SSE handling without assembling them yourself, and if you can tolerate tracking a v3 release candidate. Stay with net/http and small helper functions if your client is one endpoint with no retry policy, or if you need streaming semantics you control byte by byte, since stream.go and sse.go sit on top of the standard response body. Before committing, check the release notes for the exact v3.0.0-rc.4 tag, confirm the module path resty.dev/v3 resolves in your build, and read the godoc entry for whichever of retry.go, circuit_breaker.go or load_balancer.go you plan to rely on, because the README itself documents none of the configuration keys.

Frequently asked questions

What is go-resty/resty in Go?

It is an MIT-licensed HTTP, REST and SSE client library for Go, described in its README as a "Simple HTTP, REST, and SSE client library for Go". It requires go1.23 and above and is imported as resty.dev/v3.

What is the go-resty/resty alternative if I do not want the dependency?

The practical alternative is net/http with your own retry loop and policy code. Resty's difference is that retry.go, circuit_breaker.go, load_balancer.go and the other policy files ship as part of the library, so you configure them rather than write them.

Which Go version does go-resty/resty need?

The README states to use go1.23 and above, and go.mod declares go 1.23.0. The only external dependency listed in go.mod is golang.org/x/net.

Is go-resty/resty v3 stable enough for production?

The most recent release is v3.0.0-rc.4, dated 2026-09-06, so the v3 line has not reached a final release. The README does not state an API stability guarantee for the release candidate.

What import path does go-resty/resty v3 use?

The README states that Resty v3 provides the Go vanity URL resty.dev/v3, and go.mod declares the module as resty.dev/v3. Earlier lines used github.com/go-resty/resty/v2 and gopkg.in respectively.

Does go-resty/resty support server-sent events?

Yes. The repository description names SSE alongside HTTP and REST, and there is a dedicated sse.go file with a matching sse_test.go. Streaming is handled separately in stream.go.

Official sources

  1. go-resty/resty on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/go-resty-resty.svg)](https://hysenlabs.com/projects/go-resty-resty)