Skip to content

Commit 4899fe9

Browse files
committed
more improvements to the x/client new sub-package
1 parent 4a1f0b6 commit 4899fe9

5 files changed

Lines changed: 159 additions & 0 deletions

File tree

_examples/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
* [Multi Instances](http-server/custom-httpserver/multi/main.go)
3131
* [HTTP/3 Quic](http-server/http3-quic)
3232
* [Timeout](http-server/timeout/main.go)
33+
* HTTP Client
34+
* [Weather Client](http-client/weatherapi)
3335
* Configuration
3436
* [Functional](configuration/functional/main.go)
3537
* [Configuration Struct](configuration/from-configuration-structure/main.go)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"net/url"
6+
7+
"github.com/kataras/iris/v12"
8+
"github.com/kataras/iris/v12/x/client"
9+
)
10+
11+
// The BaseURL of our API client.
12+
const BaseURL = "https://api.weatherapi.com/v1"
13+
14+
type (
15+
Options struct {
16+
APIKey string `json:"api_key" yaml:"APIKey" toml:"APIKey"`
17+
}
18+
19+
Client struct {
20+
*client.Client
21+
}
22+
)
23+
24+
func NewClient(opts Options) *Client {
25+
apiKeyParameterSetter := client.RequestParam("key", opts.APIKey)
26+
27+
c := client.New(
28+
client.Debug,
29+
client.BaseURL(BaseURL),
30+
client.PersistentRequestOptions(apiKeyParameterSetter),
31+
)
32+
33+
return &Client{c}
34+
}
35+
36+
func (c *Client) GetCurrentByCity(ctx context.Context, city string) (resp Response, err error) {
37+
urlpath := "/current.json"
38+
// ?q=Athens&aqi=no
39+
params := client.RequestQuery(url.Values{
40+
"q": []string{city},
41+
"aqi": []string{"no"},
42+
})
43+
44+
err = c.Client.ReadJSON(ctx, &resp, iris.MethodGet, urlpath, nil, params)
45+
return
46+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package client
2+
3+
type Response struct {
4+
Location struct {
5+
Name string `json:"name"`
6+
Region string `json:"region"`
7+
Country string `json:"country"`
8+
Lat float64 `json:"lat"`
9+
Lon float64 `json:"lon"`
10+
TzID string `json:"tz_id"`
11+
LocaltimeEpoch int `json:"localtime_epoch"`
12+
Localtime string `json:"localtime"`
13+
} `json:"location"`
14+
Current struct {
15+
LastUpdatedEpoch int `json:"last_updated_epoch"`
16+
LastUpdated string `json:"last_updated"`
17+
TempC float64 `json:"temp_c"`
18+
TempF float64 `json:"temp_f"`
19+
IsDay int `json:"is_day"`
20+
Condition struct {
21+
Text string `json:"text"`
22+
Icon string `json:"icon"`
23+
Code int `json:"code"`
24+
} `json:"condition"`
25+
WindMph float64 `json:"wind_mph"`
26+
WindKph float64 `json:"wind_kph"`
27+
WindDegree int `json:"wind_degree"`
28+
WindDir string `json:"wind_dir"`
29+
PressureMb float64 `json:"pressure_mb"`
30+
PressureIn float64 `json:"pressure_in"`
31+
PrecipMm float64 `json:"precip_mm"`
32+
PrecipIn float64 `json:"precip_in"`
33+
Humidity int `json:"humidity"`
34+
Cloud int `json:"cloud"`
35+
FeelslikeC float64 `json:"feelslike_c"`
36+
FeelslikeF float64 `json:"feelslike_f"`
37+
VisKm float64 `json:"vis_km"`
38+
VisMiles float64 `json:"vis_miles"`
39+
Uv float64 `json:"uv"`
40+
GustMph float64 `json:"gust_mph"`
41+
GustKph float64 `json:"gust_kph"`
42+
} `json:"current"`
43+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/kataras/iris/v12/_examples/http-client/weatherapi/client"
8+
)
9+
10+
func main() {
11+
c := client.NewClient(client.Options{
12+
APIKey: "{YOUR_API_KEY_HERE}",
13+
})
14+
15+
resp, err := c.GetCurrentByCity(context.Background(), "Xanthi/GR")
16+
if err != nil {
17+
panic(err)
18+
}
19+
20+
fmt.Printf("Temp: %.2f(C), %.2f(F)\n", resp.Current.TempC, resp.Current.TempF)
21+
}

x/client/option.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
package client
22

33
import (
4+
"context"
5+
"fmt"
6+
"net/http"
7+
"strings"
48
"time"
59

10+
"github.com/kataras/golog"
611
"golang.org/x/time/rate"
712
)
813

@@ -46,3 +51,45 @@ func RateLimit(requestsPerSecond int) Option {
4651
c.rateLimiter = rate.NewLimiter(rate.Limit(requestsPerSecond), requestsPerSecond)
4752
}
4853
}
54+
55+
// Debug enables the client's debug logger.
56+
func Debug(c *Client) {
57+
handler := &debugRequestHandler{
58+
logger: golog.Child("Iris HTTP Client: ").SetLevel("debug"),
59+
}
60+
c.requestHandlers = append(c.requestHandlers, handler)
61+
}
62+
63+
type debugRequestHandler struct {
64+
logger *golog.Logger
65+
}
66+
67+
func (h *debugRequestHandler) getHeadersLine(headers http.Header) (headersLine string) {
68+
for k, v := range headers {
69+
headersLine += fmt.Sprintf("%s(%s), ", k, strings.Join(v, ","))
70+
}
71+
72+
headersLine = strings.TrimRight(headersLine, ", ")
73+
return
74+
}
75+
76+
func (h *debugRequestHandler) BeginRequest(ctx context.Context, req *http.Request) error {
77+
format := "%s: %s: content length: %d: headers: %s"
78+
headersLine := h.getHeadersLine(req.Header)
79+
80+
h.logger.Debugf(format, req.Method, req.URL.String(), req.ContentLength, headersLine)
81+
return nil
82+
}
83+
84+
func (h *debugRequestHandler) EndRequest(ctx context.Context, resp *http.Response, err error) error {
85+
if err != nil {
86+
h.logger.Debugf("%s: %s: ERR: %s", resp.Request.Method, resp.Request.URL.String(), err.Error())
87+
} else {
88+
format := "%s: %s: content length: %d: headers: %s"
89+
headersLine := h.getHeadersLine(resp.Header)
90+
91+
h.logger.Debugf(format, resp.Request.Method, resp.Request.URL.String(), resp.ContentLength, headersLine)
92+
}
93+
94+
return err
95+
}

0 commit comments

Comments
 (0)