diff --git a/mite/api.go b/mite/api.go index 2f66b33..dadebfe 100644 --- a/mite/api.go +++ b/mite/api.go @@ -8,8 +8,9 @@ import ( "net/url" ) -const userAgent = "mite-go/0.1 (+github.com/leanovate/mite-go)" const layout = "2006-01-02" +const contentType = "application/json" +const userAgent = "mite-go/0.1 (+github.com/leanovate/mite-go)" type MiteApi interface { TimeEntries(query *TimeEntryQuery) ([]*TimeEntry, error) @@ -22,22 +23,23 @@ type MiteApi interface { } type miteApi struct { - url string + base string key string client *http.Client } -func NewMiteApi(url string, key string) MiteApi { - return &miteApi{url: url, key: key, client: &http.Client{}} +func NewMiteApi(base string, key string) MiteApi { + return &miteApi{base: base, key: key, client: &http.Client{}} } func (a *miteApi) get(resource string, result interface{}) error { - req, err := http.NewRequest("GET", fmt.Sprintf("%s/%s", a.url, resource), nil) + req, err := http.NewRequest(http.MethodGet, a.url(resource), nil) if err != nil { return err } - req.Header.Add("X-MiteApiKey", a.key) + req.Header.Add("User-Agent", userAgent) + req.Header.Add("X-MiteApiKey", a.key) res, err := a.client.Do(req) if err != nil { @@ -45,6 +47,9 @@ func (a *miteApi) get(resource string, result interface{}) error { } defer func() { _ = res.Body.Close() }() + if err := a.check(res); err != nil { + return err + } return json.NewDecoder(res.Body).Decode(result) } @@ -63,13 +68,14 @@ func (a *miteApi) post(resource string, body interface{}, result interface{}) er return err } - req, err := http.NewRequest("POST", fmt.Sprintf("%s/%s", a.url, resource), bytes.NewBuffer(b)) + req, err := http.NewRequest(http.MethodPost, a.url(resource), bytes.NewBuffer(b)) if err != nil { return err } - req.Header.Add("X-MiteApiKey", a.key) + + req.Header.Add("Content-Type", contentType) req.Header.Add("User-Agent", userAgent) - req.Header.Add("Content-Type", "application/json") + req.Header.Add("X-MiteApiKey", a.key) res, err := a.client.Do(req) if err != nil { @@ -77,6 +83,9 @@ func (a *miteApi) post(resource string, body interface{}, result interface{}) er } defer func() { _ = res.Body.Close() }() + if err := a.check(res); err != nil { + return err + } return json.NewDecoder(res.Body).Decode(result) } @@ -87,32 +96,66 @@ func (a *miteApi) patch(resource string, body interface{}) error { return err } - req, err := http.NewRequest("PATCH", fmt.Sprintf("%s/%s", a.url, resource), bytes.NewBuffer(b)) + req, err := http.NewRequest(http.MethodPatch, a.url(resource), bytes.NewBuffer(b)) if err != nil { return err } - req.Header.Add("X-MiteApiKey", a.key) + + req.Header.Add("Content-Type", contentType) req.Header.Add("User-Agent", userAgent) - req.Header.Add("Content-Type", "application/json") + req.Header.Add("X-MiteApiKey", a.key) res, err := a.client.Do(req) + if err != nil { + return err + } defer func() { _ = res.Body.Close() }() + if err := a.check(res); err != nil { + return err + } - return err + return nil } func (a *miteApi) delete(resource string) error { - req, err := http.NewRequest("DELETE", fmt.Sprintf("%s/%s", a.url, resource), nil) + req, err := http.NewRequest(http.MethodDelete, a.url(resource), nil) if err != nil { return err } - req.Header.Add("X-MiteApiKey", a.key) + req.Header.Add("User-Agent", userAgent) + req.Header.Add("X-MiteApiKey", a.key) res, err := a.client.Do(req) + if err != nil { + return err + } defer func() { _ = res.Body.Close() }() + if err := a.check(res); err != nil { + return err + } + + return nil +} + +func (a *miteApi) url(resource string) string { + return fmt.Sprintf("%s/%s", a.base, resource) +} + +func (a *miteApi) check(res *http.Response) error { + if res.StatusCode < 400 { + return nil + } + + msg := struct { + Error string `json:"error"` + }{} + err := json.NewDecoder(res.Body).Decode(&msg) + if err != nil { + return fmt.Errorf("failed to %s %s", res.Request.Method, res.Request.RequestURI) + } - return err + return fmt.Errorf("failed to %s %s: %s", res.Request.Method, res.Request.RequestURI, msg.Error) }