HTTP Client
The RestClient provides a robust and simplified interface for making HTTP requests in Go. It encapsulates essential features for modern microservices, such as circuit breaker, retry strategies, cache support, and handling of different content types, including multipart/form-data.
Main Structure
Below is the definition of the RestClient structure:
type RestClient struct {
name string // Client identifier name
baseURL string // Base URL for all requests
retries uint8 // Maximum number of retries
retrySleep uint // Wait time between retries (seconds)
client *http.Client // Native Go HTTP client
cb *circuitbreaker.CircuitBreaker // Circuit Breaker instance
}
Configuration and Installation
To create an instance of RestClient, use the NewRestClient function with a configuration structure:
config := &RestClientConfig{
Name: "my-service-client",
BaseURL: "http://api.example.com",
Timeout: 30,
Retries: 3,
RetrySleepInSeconds: 2,
ProxyURL: "http://proxy.example.com:8080", // Optional
}
client := NewRestClient(config)
Core Features
1. Standardized Requests
The client uses generic types to facilitate automatic mapping of success and error responses.
// GET request example
response := Request[MyResponse, ErrorResponse]{
Ctx: ctx,
Client: client,
HttpMethod: http.MethodGet,
Path: "/users/1",
}.Call()
// POST request example with body (JSON)
newUser := User{Name: "John", Email: "john@example.com"}
response := Request[UserResponse, ErrorResponse]{
Ctx: ctx,
Client: client,
HttpMethod: http.MethodPost,
Path: "/users",
Body: &newUser,
}.Call()
2. File Upload (Multipart)
Native support for sending files and form fields:
file := bytes.NewBufferString("file content")
response := Request[UploadResponse, UploadError]{
Ctx: ctx,
Client: client,
HttpMethod: http.MethodPost,
Path: "/upload",
MultipartFields: map[string]any{
"file": MultipartFile{
FileName: "document.txt",
File: file,
ContentType: "text/plain",
},
"category": "personal_documents",
},
}.Call()
3. Cache Integration
It is possible to enable cache directly in the request definition to avoid repetitive calls.
response := Request[UserData, ErrorResponse]{
Ctx: ctx,
Client: client,
HttpMethod: http.MethodGet,
Path: "/users/1",
Cache: cacheDB.NewCache[UserData]("user_1_key", 10 * time.Minute),
}.Call()
4. Response Handling
The ResponseData structure simplifies checking the operation result:
if response.HasSuccess() {
data := response.SuccessBody()
// Success logic (Status 2xx)
} else if response.HasError() {
err := response.ErrorBody()
// Mapped error logic
}
// Status Code verification helpers
if response.IsSuccessfulResponse() {
// 2xx
} else if response.IsClientErrorResponse() {
// 4xx
} else if response.IsServerErrorResponse() {
// 5xx
}
Resilience and Fault Tolerance
Circuit Breaker
The client monitors the health of the target service. By default:
- The circuit opens after 5 consecutive failures.
- It remains open for 10 seconds before attempting a new connection (half-open).
Retry
Allows configuring behavior in case of temporary network failures or momentary unavailability, defining the number of attempts and the interval between them.