58 lines
1.2 KiB
Markdown
58 lines
1.2 KiB
Markdown
|
|
# httpclient
|
||
|
|
|
||
|
|
Resilient HTTP client with automatic retry and circuit breaking.
|
||
|
|
|
||
|
|
## Install
|
||
|
|
|
||
|
|
```
|
||
|
|
go get code.nochebuena.dev/go/httpclient
|
||
|
|
```
|
||
|
|
|
||
|
|
## Usage
|
||
|
|
|
||
|
|
```go
|
||
|
|
client := httpclient.NewWithDefaults(logger)
|
||
|
|
// or with custom config:
|
||
|
|
client = httpclient.New(logger, httpclient.Config{
|
||
|
|
Name: "payment-api",
|
||
|
|
MaxRetries: 3,
|
||
|
|
CBThreshold: 10,
|
||
|
|
})
|
||
|
|
|
||
|
|
resp, err := client.Do(req)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Typed JSON helper
|
||
|
|
|
||
|
|
```go
|
||
|
|
order, err := httpclient.DoJSON[Order](ctx, client, req)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Error mapping
|
||
|
|
|
||
|
|
```go
|
||
|
|
httpclient.MapStatusToError(404, "not found") // → xerrors.ErrNotFound
|
||
|
|
```
|
||
|
|
|
||
|
|
| HTTP status | xerrors code |
|
||
|
|
|---|---|
|
||
|
|
| 404 | `ErrNotFound` |
|
||
|
|
| 400 | `ErrInvalidInput` |
|
||
|
|
| 401 | `ErrUnauthorized` |
|
||
|
|
| 403 | `ErrPermissionDenied` |
|
||
|
|
| 409 | `ErrAlreadyExists` |
|
||
|
|
| 429 | `ErrUnavailable` |
|
||
|
|
| 5xx | `ErrInternal` |
|
||
|
|
|
||
|
|
## Configuration
|
||
|
|
|
||
|
|
| Env var | Default | Description |
|
||
|
|
|---|---|---|
|
||
|
|
| `HTTP_CLIENT_NAME` | `http` | Circuit breaker name |
|
||
|
|
| `HTTP_TIMEOUT` | `30s` | Overall request timeout |
|
||
|
|
| `HTTP_DIAL_TIMEOUT` | `5s` | TCP dial timeout |
|
||
|
|
| `HTTP_MAX_RETRIES` | `3` | Retry attempts |
|
||
|
|
| `HTTP_RETRY_DELAY` | `1s` | Base retry delay |
|
||
|
|
| `HTTP_CB_THRESHOLD` | `10` | Consecutive failures before open |
|
||
|
|
| `HTTP_CB_TIMEOUT` | `1m` | Time before half-open retry |
|