more improvements to the x/client new sub-package

This commit is contained in:
Gerasimos (Makis) Maropoulos 2022-01-23 01:21:31 +02:00
parent 4a1f0b6e9e
commit 4899fe95f4
No known key found for this signature in database
GPG Key ID: 66FCC29BD385FCA6
5 changed files with 159 additions and 0 deletions

View File

@ -30,6 +30,8 @@
* [Multi Instances](http-server/custom-httpserver/multi/main.go) * [Multi Instances](http-server/custom-httpserver/multi/main.go)
* [HTTP/3 Quic](http-server/http3-quic) * [HTTP/3 Quic](http-server/http3-quic)
* [Timeout](http-server/timeout/main.go) * [Timeout](http-server/timeout/main.go)
* HTTP Client
* [Weather Client](http-client/weatherapi)
* Configuration * Configuration
* [Functional](configuration/functional/main.go) * [Functional](configuration/functional/main.go)
* [Configuration Struct](configuration/from-configuration-structure/main.go) * [Configuration Struct](configuration/from-configuration-structure/main.go)

View File

@ -0,0 +1,46 @@
package client
import (
"context"
"net/url"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/x/client"
)
// The BaseURL of our API client.
const BaseURL = "https://api.weatherapi.com/v1"
type (
Options struct {
APIKey string `json:"api_key" yaml:"APIKey" toml:"APIKey"`
}
Client struct {
*client.Client
}
)
func NewClient(opts Options) *Client {
apiKeyParameterSetter := client.RequestParam("key", opts.APIKey)
c := client.New(
client.Debug,
client.BaseURL(BaseURL),
client.PersistentRequestOptions(apiKeyParameterSetter),
)
return &Client{c}
}
func (c *Client) GetCurrentByCity(ctx context.Context, city string) (resp Response, err error) {
urlpath := "/current.json"
// ?q=Athens&aqi=no
params := client.RequestQuery(url.Values{
"q": []string{city},
"aqi": []string{"no"},
})
err = c.Client.ReadJSON(ctx, &resp, iris.MethodGet, urlpath, nil, params)
return
}

View File

@ -0,0 +1,43 @@
package client
type Response struct {
Location struct {
Name string `json:"name"`
Region string `json:"region"`
Country string `json:"country"`
Lat float64 `json:"lat"`
Lon float64 `json:"lon"`
TzID string `json:"tz_id"`
LocaltimeEpoch int `json:"localtime_epoch"`
Localtime string `json:"localtime"`
} `json:"location"`
Current struct {
LastUpdatedEpoch int `json:"last_updated_epoch"`
LastUpdated string `json:"last_updated"`
TempC float64 `json:"temp_c"`
TempF float64 `json:"temp_f"`
IsDay int `json:"is_day"`
Condition struct {
Text string `json:"text"`
Icon string `json:"icon"`
Code int `json:"code"`
} `json:"condition"`
WindMph float64 `json:"wind_mph"`
WindKph float64 `json:"wind_kph"`
WindDegree int `json:"wind_degree"`
WindDir string `json:"wind_dir"`
PressureMb float64 `json:"pressure_mb"`
PressureIn float64 `json:"pressure_in"`
PrecipMm float64 `json:"precip_mm"`
PrecipIn float64 `json:"precip_in"`
Humidity int `json:"humidity"`
Cloud int `json:"cloud"`
FeelslikeC float64 `json:"feelslike_c"`
FeelslikeF float64 `json:"feelslike_f"`
VisKm float64 `json:"vis_km"`
VisMiles float64 `json:"vis_miles"`
Uv float64 `json:"uv"`
GustMph float64 `json:"gust_mph"`
GustKph float64 `json:"gust_kph"`
} `json:"current"`
}

View File

@ -0,0 +1,21 @@
package main
import (
"context"
"fmt"
"github.com/kataras/iris/v12/_examples/http-client/weatherapi/client"
)
func main() {
c := client.NewClient(client.Options{
APIKey: "{YOUR_API_KEY_HERE}",
})
resp, err := c.GetCurrentByCity(context.Background(), "Xanthi/GR")
if err != nil {
panic(err)
}
fmt.Printf("Temp: %.2f(C), %.2f(F)\n", resp.Current.TempC, resp.Current.TempF)
}

View File

@ -1,8 +1,13 @@
package client package client
import ( import (
"context"
"fmt"
"net/http"
"strings"
"time" "time"
"github.com/kataras/golog"
"golang.org/x/time/rate" "golang.org/x/time/rate"
) )
@ -46,3 +51,45 @@ func RateLimit(requestsPerSecond int) Option {
c.rateLimiter = rate.NewLimiter(rate.Limit(requestsPerSecond), requestsPerSecond) c.rateLimiter = rate.NewLimiter(rate.Limit(requestsPerSecond), requestsPerSecond)
} }
} }
// Debug enables the client's debug logger.
func Debug(c *Client) {
handler := &debugRequestHandler{
logger: golog.Child("Iris HTTP Client: ").SetLevel("debug"),
}
c.requestHandlers = append(c.requestHandlers, handler)
}
type debugRequestHandler struct {
logger *golog.Logger
}
func (h *debugRequestHandler) getHeadersLine(headers http.Header) (headersLine string) {
for k, v := range headers {
headersLine += fmt.Sprintf("%s(%s), ", k, strings.Join(v, ","))
}
headersLine = strings.TrimRight(headersLine, ", ")
return
}
func (h *debugRequestHandler) BeginRequest(ctx context.Context, req *http.Request) error {
format := "%s: %s: content length: %d: headers: %s"
headersLine := h.getHeadersLine(req.Header)
h.logger.Debugf(format, req.Method, req.URL.String(), req.ContentLength, headersLine)
return nil
}
func (h *debugRequestHandler) EndRequest(ctx context.Context, resp *http.Response, err error) error {
if err != nil {
h.logger.Debugf("%s: %s: ERR: %s", resp.Request.Method, resp.Request.URL.String(), err.Error())
} else {
format := "%s: %s: content length: %d: headers: %s"
headersLine := h.getHeadersLine(resp.Header)
h.logger.Debugf(format, resp.Request.Method, resp.Request.URL.String(), resp.ContentLength, headersLine)
}
return err
}