Skip to content

Commit fa99930

Browse files
authored
feat(fxhttpclient): Provided module (#38)
1 parent a64c626 commit fa99930

File tree

13 files changed

+1222
-0
lines changed

13 files changed

+1222
-0
lines changed

.github/workflows/coverage.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ jobs:
3232
- "fxconfig"
3333
- "fxgenerate"
3434
- "fxhealthcheck"
35+
- "fxhttpclient"
3536
- "fxlog"
3637
- "fxmetrics"
3738
- "fxorm"

.github/workflows/fxhttpclient-ci.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: "fxhttpclient-ci"
2+
3+
on:
4+
push:
5+
branches:
6+
- "feat**"
7+
- "fix**"
8+
- "hotfix**"
9+
- "chore**"
10+
paths:
11+
- "fxhttpclient/**.go"
12+
- "fxhttpclient/go.mod"
13+
- "fxhttpclient/go.sum"
14+
pull_request:
15+
types:
16+
- opened
17+
- synchronize
18+
- reopened
19+
branches:
20+
- main
21+
paths:
22+
- "fxhttpclient/**.go"
23+
- "fxhttpclient/go.mod"
24+
- "fxhttpclient/go.sum"
25+
26+
jobs:
27+
ci:
28+
uses: ./.github/workflows/common-ci.yml
29+
secrets: inherit
30+
with:
31+
module: "fxhttpclient"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Yokai's `Fx modules` are the plugins for your Yokai application.
2525
| [fxconfig](fxconfig) | Fx module for [config](config) |
2626
| [fxgenerate](fxgenerate) | Fx module for [generate](generate) |
2727
| [fxhealthcheck](fxhealthcheck) | Fx module for [healthcheck](healthcheck) |
28+
| [fxhttpclient](fxhttpclient) | Fx module for [httpclient](httpclient) |
2829
| [fxlog](fxlog) | Fx module for [log](log) |
2930
| [fxmetrics](fxmetrics) | Fx module for [prometheus](https://github.com/prometheus/client_golang) |
3031
| [fxorm](fxorm) | Fx module for [orm](orm) |

fxhttpclient/.golangci.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
run:
2+
timeout: 5m
3+
concurrency: 8
4+
5+
linters:
6+
enable:
7+
- asasalint
8+
- asciicheck
9+
- bidichk
10+
- bodyclose
11+
- containedctx
12+
- contextcheck
13+
- cyclop
14+
- decorder
15+
- dogsled
16+
- dupl
17+
- durationcheck
18+
- errcheck
19+
- errchkjson
20+
- errname
21+
- errorlint
22+
- exhaustive
23+
- forbidigo
24+
- forcetypeassert
25+
- gocognit
26+
- goconst
27+
- gocritic
28+
- gocyclo
29+
- godot
30+
- godox
31+
- gofmt
32+
- goheader
33+
- gomoddirectives
34+
- gomodguard
35+
- goprintffuncname
36+
- gosec
37+
- gosimple
38+
- govet
39+
- grouper
40+
- importas
41+
- ineffassign
42+
- interfacebloat
43+
- logrlint
44+
- maintidx
45+
- makezero
46+
- misspell
47+
- nestif
48+
- nilerr
49+
- nilnil
50+
- nlreturn
51+
- nolintlint
52+
- nosprintfhostport
53+
- prealloc
54+
- predeclared
55+
- promlinter
56+
- reassign
57+
- staticcheck
58+
- tenv
59+
- thelper
60+
- tparallel
61+
- typecheck
62+
- unconvert
63+
- unparam
64+
- unused
65+
- usestdlibvars
66+
- whitespace

fxhttpclient/README.md

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# Fx Http Client Module
2+
3+
[![ci](https://github.com/ankorstore/yokai/actions/workflows/fxhttpclient-ci.yml/badge.svg)](https://github.com/ankorstore/yokai/actions/workflows/fxhttpclient-ci.yml)
4+
[![go report](https://goreportcard.com/badge/github.com/ankorstore/yokai/fxhttpclient)](https://goreportcard.com/report/github.com/ankorstore/yokai/fxhttpclient)
5+
[![codecov](https://codecov.io/gh/ankorstore/yokai/graph/badge.svg?token=ghUBlFsjhR&flag=fxhttpclient)](https://app.codecov.io/gh/ankorstore/yokai/tree/main/fxhttpclient)
6+
[![Deps](https://img.shields.io/badge/osi-deps-blue)](https://deps.dev/go/github.com%2Fankorstore%2Fyokai%2Ffxhttpclient)
7+
[![PkgGoDev](https://pkg.go.dev/badge/github.com/ankorstore/yokai/fxhttpclient)](https://pkg.go.dev/github.com/ankorstore/yokai/fxhttpclient)
8+
9+
> [Fx](https://uber-go.github.io/fx/) module for [httpclient](https://github.com/ankorstore/yokai/tree/main/httpclient).
10+
11+
<!-- TOC -->
12+
* [Installation](#installation)
13+
* [Features](#features)
14+
* [Documentation](#documentation)
15+
* [Dependencies](#dependencies)
16+
* [Loading](#loading)
17+
* [Configuration](#configuration)
18+
* [Override](#override)
19+
<!-- TOC -->
20+
21+
## Installation
22+
23+
```shell
24+
go get github.com/ankorstore/yokai/fxhttpclient
25+
```
26+
27+
## Features
28+
29+
This module provides the possibility to provide to your Fx application a `http.Client` with:
30+
31+
- configurable transport
32+
- automatic and configurable request / response logging
33+
- configurable request / response tracing
34+
35+
## Documentation
36+
37+
### Dependencies
38+
39+
This module is intended to be used alongside:
40+
41+
- the [fxconfig](https://github.com/ankorstore/yokai/tree/main/fxconfig) module
42+
- the [fxlog](https://github.com/ankorstore/yokai/tree/main/fxlog) module
43+
- the [fxtrace](https://github.com/ankorstore/yokai/tree/main/fxtrace) module
44+
45+
### Loading
46+
47+
To load the module in your Fx application:
48+
49+
```go
50+
package main
51+
52+
import (
53+
"net/http"
54+
55+
"github.com/ankorstore/yokai/fxconfig"
56+
"github.com/ankorstore/yokai/fxhttpclient"
57+
"github.com/ankorstore/yokai/fxlog"
58+
"github.com/ankorstore/yokai/fxtrace"
59+
"go.uber.org/fx"
60+
)
61+
62+
func main() {
63+
fx.New(
64+
fxconfig.FxConfigModule, // load the module dependencies
65+
fxlog.FxLogModule,
66+
fxtrace.FxTraceModule,
67+
fxhttpclient.FxHttpClientModule, // load the module
68+
fx.Invoke(func(httpClient *http.Client) { // invoke the client
69+
resp, err := httpClient.Get("https://example.com")
70+
}),
71+
).Run()
72+
}
73+
```
74+
75+
### Configuration
76+
77+
Configuration reference:
78+
79+
```yaml
80+
# ./configs/config.yaml
81+
app:
82+
name: app
83+
env: dev
84+
version: 0.1.0
85+
debug: true
86+
modules:
87+
log:
88+
level: info
89+
output: stdout
90+
trace:
91+
processor:
92+
type: stdout
93+
http:
94+
client:
95+
timeout: 30 # in seconds, 30 by default
96+
transport:
97+
max_idle_connections: 100 # 100 by default
98+
max_connections_per_host: 100 # 100 by default
99+
max_idle_connections_per_host: 100 # 100 by default
100+
log:
101+
request:
102+
enabled: true # to log request details, disabled by default
103+
body: true # to add request body to request details, disabled by default
104+
level: info # log level for request logging
105+
response:
106+
enabled: true # to log response details, disabled by default
107+
body: true # to add response body to request details, disabled by default
108+
level: info # log level for response logging
109+
level_from_response: true # to use response code for response logging
110+
trace:
111+
enabled: true # to trace http calls, disabled by default
112+
```
113+
114+
If `http.client.log.response.level_from_response=true`, the response code will be used to determinate the log level:
115+
116+
- `code < 400`: log level configured in `http.client.log.response.level`
117+
- `400 <= code < 500`: log level `warn`
118+
- `code >= 500`: log level `error`
119+
120+
Notes:
121+
122+
- the http client logging will be based on the [fxlog](https://github.com/ankorstore/yokai/tree/main/fxlog) module
123+
configuration
124+
- the http client tracing will be based on the [fxtrace](https://github.com/ankorstore/yokai/tree/main/fxtrace) module
125+
configuration
126+
127+
### Override
128+
129+
By default, the `http.Client` is created by
130+
the [DefaultHttpClientFactory](https://github.com/ankorstore/yokai/blob/main/httpclient/factory.go).
131+
132+
If needed, you can provide your own factory and override the module:
133+
134+
```go
135+
package main
136+
137+
import (
138+
"net/http"
139+
140+
"github.com/ankorstore/yokai/fxconfig"
141+
"github.com/ankorstore/yokai/fxhttpclient"
142+
"github.com/ankorstore/yokai/fxlog"
143+
"github.com/ankorstore/yokai/fxtrace"
144+
"github.com/ankorstore/yokai/httpclient"
145+
"go.uber.org/fx"
146+
)
147+
148+
type CustomHttpClientFactory struct{}
149+
150+
func NewCustomHttpClientFactory() httpclient.HttpClientFactory {
151+
return &CustomHttpClientFactory{}
152+
}
153+
154+
func (f *CustomHttpClientFactory) Create(options ...httpclient.HttpClientOption) (*http.Client, error) {
155+
return http.DefaultClient, nil
156+
}
157+
158+
func main() {
159+
fx.New(
160+
fxconfig.FxConfigModule, // load the module dependencies
161+
fxlog.FxLogModule,
162+
fxtrace.FxTraceModule,
163+
fxhttpclient.FxHttpClientModule, // load the module
164+
fx.Decorate(NewCustomHttpClientFactory), // override the module with a custom factory
165+
fx.Invoke(func(httpClient *http.Client) { // invoke the custom client
166+
// ...
167+
}),
168+
).Run()
169+
}
170+
```

fxhttpclient/go.mod

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
module github.com/ankorstore/yokai/fxhttpclient
2+
3+
go 1.20
4+
5+
require (
6+
github.com/ankorstore/yokai/config v1.1.0
7+
github.com/ankorstore/yokai/fxconfig v1.0.0
8+
github.com/ankorstore/yokai/fxlog v1.0.0
9+
github.com/ankorstore/yokai/fxtrace v1.1.0
10+
github.com/ankorstore/yokai/httpclient v1.0.0
11+
github.com/ankorstore/yokai/log v1.0.0
12+
github.com/ankorstore/yokai/trace v1.0.0
13+
github.com/stretchr/testify v1.8.4
14+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0
15+
go.opentelemetry.io/otel v1.16.0
16+
go.opentelemetry.io/otel/trace v1.16.0
17+
go.uber.org/fx v1.20.1
18+
)
19+
20+
require (
21+
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
22+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
23+
github.com/felixge/httpsnoop v1.0.3 // indirect
24+
github.com/fsnotify/fsnotify v1.7.0 // indirect
25+
github.com/go-logr/logr v1.2.4 // indirect
26+
github.com/go-logr/stdr v1.2.2 // indirect
27+
github.com/golang/protobuf v1.5.3 // indirect
28+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
29+
github.com/hashicorp/hcl v1.0.0 // indirect
30+
github.com/magiconair/properties v1.8.7 // indirect
31+
github.com/mattn/go-colorable v0.1.13 // indirect
32+
github.com/mattn/go-isatty v0.0.19 // indirect
33+
github.com/mitchellh/mapstructure v1.5.0 // indirect
34+
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
35+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
36+
github.com/rs/zerolog v1.31.0 // indirect
37+
github.com/sagikazarmark/locafero v0.4.0 // indirect
38+
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
39+
github.com/sourcegraph/conc v0.3.0 // indirect
40+
github.com/spf13/afero v1.11.0 // indirect
41+
github.com/spf13/cast v1.6.0 // indirect
42+
github.com/spf13/pflag v1.0.5 // indirect
43+
github.com/spf13/viper v1.18.2 // indirect
44+
github.com/subosito/gotenv v1.6.0 // indirect
45+
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect
46+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect
47+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 // indirect
48+
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.16.0 // indirect
49+
go.opentelemetry.io/otel/metric v1.16.0 // indirect
50+
go.opentelemetry.io/otel/sdk v1.16.0 // indirect
51+
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
52+
go.uber.org/dig v1.17.1 // indirect
53+
go.uber.org/multierr v1.11.0 // indirect
54+
go.uber.org/zap v1.26.0 // indirect
55+
golang.org/x/exp v0.0.0-20240110193028-0dcbfd608b1e // indirect
56+
golang.org/x/net v0.19.0 // indirect
57+
golang.org/x/sys v0.16.0 // indirect
58+
golang.org/x/text v0.14.0 // indirect
59+
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect
60+
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect
61+
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
62+
google.golang.org/grpc v1.59.0 // indirect
63+
google.golang.org/protobuf v1.31.0 // indirect
64+
gopkg.in/ini.v1 v1.67.0 // indirect
65+
gopkg.in/yaml.v3 v3.0.1 // indirect
66+
)

0 commit comments

Comments
 (0)