fast-shot
Hit your API targets with rapid-fire precision using Go's fastest and simple HTTP Client
About fast-shot
Fast Shot is a robust, feature-rich, and highly configurable HTTP client for Go. Crafted with modern Go practices in mind, it offers a fluent, chainable API that allows for clean, idiomatic code.
Table of Contents
Why Fast Shot?
- Fluent & Chainable API: Write expressive, readable, and flexible HTTP client code.
- Ease of Use: Reduce boilerplate, making HTTP requests as straightforward as possible.
- Rich Features: From headers to query parameters and JSON support, Fast Shot covers your needs.
- Advanced Retry Mechanism: Built-in support for retries with various backoff strategies.
Features 🌟
- Fluent and chainable API for clean, expressive code
- Comprehensive HTTP method support (GET, POST, PUT, DELETE, etc.)
- Flexible authentication options (Bearer Token, Basic Auth, Custom)
- Easy manipulation of headers, cookies, and query parameters
- Advanced retry mechanism with customizable backoff strategies
- Pre-request and post-response hooks for observability and custom logic
- Client-side load balancing for improved reliability
- JSON request and response support
- XML request and response support
- Timeout and redirect control
- Proxy support
- Extensible and customizable for specific needs
- Well-tested and production-ready
Installation 🔧
Fast Shot requires Go 1.27 or later. To install it, run:
go get github.com/opus-domini/fast-shot
Quick Start 🚀
Here's how you can make a simple POST using Fast Shot:
package main
import (
"fmt"
fastshot "github.com/opus-domini/fast-shot"
"github.com/opus-domini/fast-shot/constant/mime"
)
func main() {
client := fastshot.NewClient("https://api.example.com").
Auth().BearerToken("your_token_here").
Build()
payload := map[string]any{
"key1": "value1",
"key2": "value2",
}
response, err := client.POST("/endpoint").
Header().AddAccept(mime.JSON).
Body().AsJSON(payload).
Send()
// Check for request send problems.
if err != nil {
panic(err) // (¬_¬")
}
// Check for (4xx || 5xx) errors response.
if response.Status().IsError() {
panic(response.Body().AsString()) // ¯\_(ツ)_/¯
}
// Decode straight into a typed value (Go 1.27 generic method).
result, err := response.Body().AsJSON[map[string]any]()
// Congrats! Do something awesome with the result (¬‿¬)
fmt.Println(result)
}
Advanced Usage 🤖
Fluent API
Easily chain multiple settings in a single line:
client := fastshot.NewClient("https://api.example.com").
Auth().BearerToken("your-bearer-token").
Header().Add("My-Header", "My-Value").
Config().SetTimeout(30 * time.Second).
Build()
Advanced Retry Mechanism
Handle transient failures with customizable backoff strategies:
client.POST("/resource").
Retry().SetExponentialBackoff(2 * time.Second, 5, 2.0).
Send()
This new retry feature supports:
- Constant backoff
- Exponential backoff
- Full jitter for both constant and exponential backoff
- Custom retry conditions
- Maximum delay setting
Request Hooks
Inject custom logic before sending requests and after receiving responses. Useful for logging, metrics, tracing, request signing, and audit logs:
client := fastshot.NewClient("https://api.example.com").
Hook().OnBeforeRequest(func(req *http.Request) error {
req.Header.Set("X-Request-ID", uuid.New().String()) // stdlib uuid, Go 1.27+
return nil
}).
Hook().OnAfterResponse(func(req *http.Request, resp *http.Response) {
log.Printf("%s %s → %d", req.Method, req.URL, resp.StatusCode)
}).
Build()
Hooks can also be set per-request:
client.GET("/resource").
Hook().OnBeforeRequest(func(req *http.Request) error {
// Only for this request
return nil
}).
Send()
Key behaviors:
- Client hooks run before request hooks (same ordering as headers and cookies)
- Hooks run on every attempt, including retries
- A before-request hook returning an error aborts the request
- After-response hooks are observational and do not return errors
Generic Response Decoding (Go 1.27)
Skip the pre-allocated destination and decode straight into a typed value:
type User struct {
Name string `json:"name"`
}
user, err := response.Body().AsJSON[User]()
// also available: response.Body().AsXML[User]()
Pluggable JSON Codec (encoding/json/v2)
Bodies are encoded/decoded with the standard encoding/json/v2 (Go 1.27+):
strict, interoperable defaults — invalid UTF-8, duplicate object keys, and
trailing data are rejected.
Need the lenient encoding/json (v1) semantics? Opt in:
client := fastshot.NewClient("https://api.example.com").
Config().SetJSONCodec(fastshot.NewJSONv1Codec()).
Build()
Bring your own codec by implementing fastshot.JSONCodec (Encode/Decode funcs).
Out-of-the-Box Support for Client Load Balancing
Effortlessly manage multiple endpoints:
client := fastshot.NewClientLoadBalancer([]string{
"https://api1.example.com",
"https://api2.example.com",
"https://api3.example.com",
}).
Config().SetTimeout(time.Second * 10).
Build()
This feature allows you to distribute network traffic across several servers, enhancing the performance and reliability of your applications.
Authentication
Fast Shot supports various types of authentication:
// Bearer Token
builder.Auth().BearerToken("your-bearer-token")
// Basic Authentication
builder.Auth().BasicAuth("username", "password")
// Custom Authentication
builder.Auth().Set("custom-authentication-header")
Custom Headers and Cookies
Add your own headers and cookies effortlessly:
// Add Custom Header
builder.Header().
Add("header", "value")
// Add Multiple Custom Headers
builder.Header().
AddAll(map[header.Type]string{
"key1": "value1",
"key2": "value2",
"key3": "value3",
})
// Add Custom Cookie
builder.Cookie().
Add(&http.Cookie{Name: "session_id", Value: "id"})
Advanced Configurations
Control every aspect of the HTTP client:
// Set Timeout
builder.Config().
SetTimeout(time.Second * 30)
// Set Follow Redirect
builder.Config().
SetFollowRedirects(false)
// Set Custom Transport
builder.Config().
SetCustomTransport(myCustomTransport)
// Set Proxy
builder.Config().
SetProxy("http://my-proxy-server:port")
Response Handling
Extract information from the response with ease:
// Fluent response status check
response.Status()
// Easy response body access and conversion
response.Body()
// Get response headers to inspect
response.Header()
// Get response cookies for further processing
response.Cookie()
// Get raw response if needed
response.Raw()
// and more...
Contributing 🤝
We welcome contributions to Fast Shot! Here's how you can contribute:
- Fork the repository
- Create a new branch for your feature or bug fix
- Write your code and tests
- Ensure all tests pass
- Submit a pull request
Please make sure to update tests as appropriate and adhere to the existing coding style.
For more detailed information, check out our CONTRIBUTING.md file.
Frequently Asked Questions
What is fast-shot?
fast-shot is a Networking library for the Go programming language. Hit your API targets with rapid-fire precision using Go's fastest and simple HTTP Client
How do I install fast-shot?
Install fast-shot with the Go module system using `go get opus-domini/fast-shot`. Check the repository for the current installation instructions.
What category does fast-shot belong to?
fast-shot is listed under Networking, specifically HTTP Clients.