92 lines
1.8 KiB
Go
92 lines
1.8 KiB
Go
|
package client
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"net/http"
|
||
|
"net/url"
|
||
|
"strings"
|
||
|
|
||
|
"git.ctrlz.es/mgdelacroix/birthdaybot/model"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
ErrEmptyURL = errors.New("URL cannot be empty")
|
||
|
)
|
||
|
|
||
|
type Client struct {
|
||
|
url string
|
||
|
httpClient *http.Client
|
||
|
headers map[string]string
|
||
|
}
|
||
|
|
||
|
func New(opts ...Option) (*Client, error) {
|
||
|
client := &Client{
|
||
|
httpClient: &http.Client{},
|
||
|
}
|
||
|
|
||
|
for _, opt := range opts {
|
||
|
client = opt(client)
|
||
|
}
|
||
|
|
||
|
if client.url == "" {
|
||
|
return nil, ErrEmptyURL
|
||
|
}
|
||
|
|
||
|
return client, nil
|
||
|
}
|
||
|
|
||
|
func (c *Client) Do(ctx context.Context, method, path, data string, headers map[string]string) (*http.Response, error) {
|
||
|
url, err := url.JoinPath(c.url, path)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("cannot build request url: %w", err)
|
||
|
}
|
||
|
|
||
|
req, err := http.NewRequestWithContext(ctx, method, url, strings.NewReader(data))
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("cannot create request: %w", err)
|
||
|
}
|
||
|
|
||
|
for k, v := range c.headers {
|
||
|
req.Header.Set(k, v)
|
||
|
}
|
||
|
|
||
|
for k, v := range headers {
|
||
|
req.Header.Set(k, v)
|
||
|
}
|
||
|
|
||
|
resp, err := c.httpClient.Do(req)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("cannot do request: %w", err)
|
||
|
}
|
||
|
|
||
|
return resp, nil
|
||
|
}
|
||
|
|
||
|
func (c *Client) Health(ctx context.Context) (bool, error) {
|
||
|
resp, err := c.Do(ctx, http.MethodGet, "/health", "", nil)
|
||
|
if err != nil {
|
||
|
return false, err
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
|
||
|
return resp.StatusCode == 200, nil
|
||
|
}
|
||
|
|
||
|
func (c *Client) NextBirthdays(ctx context.Context) ([]*model.Birthday, error) {
|
||
|
resp, err := c.Do(ctx, http.MethodGet, "/next_birthdays", "", nil)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
|
||
|
var birthdays []*model.Birthday
|
||
|
if err := json.NewDecoder(resp.Body).Decode(&birthdays); err != nil {
|
||
|
return nil, fmt.Errorf("cannot decode birthdays: %w", err)
|
||
|
}
|
||
|
|
||
|
return birthdays, nil
|
||
|
}
|