From 99207293a2d5db3556ebb651ad694c162c1e6167 Mon Sep 17 00:00:00 2001 From: Steven Polley Date: Sun, 22 Jul 2018 19:35:10 -0600 Subject: [PATCH] go-cw style request wrapping --- itglue/flexible-asset-types.go | 12 ++--- itglue/flexible-assets.go | 15 ++---- itglue/itglue.go | 81 +++------------------------------ itglue/organization-statuses.go | 12 ++--- itglue/organization-types.go | 11 ++--- itglue/organizations.go | 35 +++++++------- itglue/user-metrics.go | 12 ++--- itglue/users.go | 12 ++--- 8 files changed, 48 insertions(+), 142 deletions(-) diff --git a/itglue/flexible-asset-types.go b/itglue/flexible-asset-types.go index 35cb9b1..1921f42 100644 --- a/itglue/flexible-asset-types.go +++ b/itglue/flexible-asset-types.go @@ -34,18 +34,14 @@ type FlexibleAssetTypeList struct { } func (itg *ITGAPI) GetFlexibleAssetTypes() (*FlexibleAssetTypeList, error) { - itgurl, err := itg.BuildURL("/flexible_asset_types") + req := itg.NewRequest("/flexible_asset_types", "GET", nil) + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build URL: %s", err) - } - body, err := itg.GetRequest(itgurl) - - if err != nil { - return nil, fmt.Errorf("request failed: %s", err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } flexibleAssetTypes := &FlexibleAssetTypeList{} - err = json.Unmarshal(body, flexibleAssetTypes) + err = json.Unmarshal(req.Body, flexibleAssetTypes) if err != nil { return nil, fmt.Errorf("could not get flexible asset types: %s", err) } diff --git a/itglue/flexible-assets.go b/itglue/flexible-assets.go index 21a3ead..35e2a49 100644 --- a/itglue/flexible-assets.go +++ b/itglue/flexible-assets.go @@ -33,21 +33,16 @@ type FlexibleAssetList struct { } func (itg *ITGAPI) GetFlexibleAssets(flexibleAssetTypeID int) error { - itgurl, err := itg.BuildURL("/flexible_assets") + req := itg.NewRequest("/flexible_assets", "GET", nil) + err := req.Do() if err != nil { - return fmt.Errorf("could not build URL: %s", err) + return fmt.Errorf("request failed for %s: %s", req.RestAction, err) } - body, err := itg.GetRequest(itgurl) - - if err != nil { - return fmt.Errorf("request failed: %s", err) - } - - fmt.Println(string(body)) + fmt.Println(string(req.Body)) /* flexibleAssets := &FlexibleAssetList{} - err = json.Unmarshal(body, flexibleAssets) + err = json.Unmarshal(req.Body, flexibleAssets) if err != nil { return nil, fmt.Errorf("could not get flexible asset: %s", err) } diff --git a/itglue/itglue.go b/itglue/itglue.go index f6d9829..7019686 100644 --- a/itglue/itglue.go +++ b/itglue/itglue.go @@ -3,7 +3,6 @@ package itglue import ( "bytes" "fmt" - "io" "io/ioutil" "net/http" "net/url" @@ -39,6 +38,12 @@ type Request struct { PageSize int } +//NewITGAPI expects the API key to be passed to it +//Returns a pointer to an ITGAPI struct +func NewITGAPI(apiKey string) *ITGAPI { + return &ITGAPI{Site: "https://api.itglue.com", APIKey: apiKey} +} + //NewRequest is a function which takes the mandatory fields to perform a request to the CW API and returns a pointer to a Request struct func (itg *ITGAPI) NewRequest(restAction, method string, body []byte) *Request { req := Request{ITG: itg, RestAction: restAction, Method: method, Body: body} @@ -82,12 +87,6 @@ func (req *Request) Do() error { return nil } -//NewITGAPI expects the API key to be passed to it -//Returns a pointer to an ITGAPI struct -func NewITGAPI(apiKey string) *ITGAPI { - return &ITGAPI{Site: "https://api.itglue.com", APIKey: apiKey} -} - func getHTTPResponseBody(resp *http.Response) ([]byte, error) { if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("ITG returned HTTP status code %s\n%s", resp.Status, resp.Body) @@ -112,71 +111,3 @@ func (itg *ITGAPI) BuildURL(restAction string) (*url.URL, error) { itgurl.Path += restAction return itgurl, nil } - -//GetRequest allows a custom GET request to the API to be made. -//Also used internally by this package by the binding functions -//Expects URL to be passed -//Returns the response body as a byte slice -func (itg *ITGAPI) GetRequest(itgurl *url.URL) ([]byte, error) { - client := &http.Client{} - req, err := http.NewRequest("GET", itgurl.String(), nil) - if err != nil { - return nil, fmt.Errorf("could not create http request: %s", err) - } - req.Header.Set("Content-Type", "application/vnd.api+json") - req.Header.Set("x-api-key", itg.APIKey) - req.Header.Set("cache-control", "no-cache") - response, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("http request failed: %s", err) - } - defer response.Body.Close() - - return getHTTPResponseBody(response) -} - -//PostRequest allows a custom POST request tot he API to be made -//Also used internally by this package by the binding functions -//Expects a URL and a body to be passed -//Returns the response body as a byte slice -func (itg *ITGAPI) PostRequest(itgurl *url.URL, body io.Reader) ([]byte, error) { - client := &http.Client{} - req, err := http.NewRequest("POST", itgurl.String(), body) - if err != nil { - return nil, fmt.Errorf("could not create http request: %s", err) - } - req.Header.Set("Content-Type", "application/vnd.api+json") - req.Header.Set("x-api-key", itg.APIKey) - req.Header.Set("cache-control", "no-cache") - response, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("http request failed: %s", err) - } - defer response.Body.Close() - - return getHTTPResponseBody(response) - -} - -//PatchRequest allows a custom PATCH request tot he API to be made -//Also used internally by this package by the binding functions -//Expects a URL and a body to be passed -//Returns the response body as a byte slice -func (itg *ITGAPI) PatchRequest(itgurl *url.URL, body io.Reader) ([]byte, error) { - client := &http.Client{} - req, err := http.NewRequest("PATCH", itgurl.String(), body) - if err != nil { - return nil, fmt.Errorf("could not create http request: %s", err) - } - req.Header.Set("Content-Type", "application/vnd.api+json") - req.Header.Set("x-api-key", itg.APIKey) - req.Header.Set("cache-control", "no-cache") - response, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("http request failed: %s", err) - } - defer response.Body.Close() - - return getHTTPResponseBody(response) - -} diff --git a/itglue/organization-statuses.go b/itglue/organization-statuses.go index 81df394..778511c 100644 --- a/itglue/organization-statuses.go +++ b/itglue/organization-statuses.go @@ -30,18 +30,14 @@ type OrganizationStatusList struct { } func (itg *ITGAPI) GetOrganizationStatuses() (*OrganizationStatusList, error) { - itgurl, err := itg.BuildURL("/organization_statuses") + req := itg.NewRequest("/organization_statuses", "GET", nil) + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build URL: %s", err) - } - body, err := itg.GetRequest(itgurl) - - if err != nil { - return nil, fmt.Errorf("request failed: %s", err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } organizationStatuses := &OrganizationStatusList{} - err = json.Unmarshal(body, organizationStatuses) + err = json.Unmarshal(req.Body, organizationStatuses) if err != nil { return nil, fmt.Errorf("could not get organization types: %s", err) } diff --git a/itglue/organization-types.go b/itglue/organization-types.go index 1fbb3b6..3c80eeb 100644 --- a/itglue/organization-types.go +++ b/itglue/organization-types.go @@ -31,17 +31,14 @@ type OrganizationTypeList struct { ///organization_types func (itg *ITGAPI) GetOrganizationTypes() (*OrganizationTypeList, error) { - itgurl, err := itg.BuildURL("/organization_types") + req := itg.NewRequest("/organization_types", "GET", nil) + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build URL: %s", err) - } - body, err := itg.GetRequest(itgurl) - if err != nil { - return nil, fmt.Errorf("request failed: %s", err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } organizationTypes := &OrganizationTypeList{} - err = json.Unmarshal(body, organizationTypes) + err = json.Unmarshal(req.Body, organizationTypes) if err != nil { return nil, fmt.Errorf("could not get organization types: %s", err) } diff --git a/itglue/organizations.go b/itglue/organizations.go index 1592404..7e52f77 100644 --- a/itglue/organizations.go +++ b/itglue/organizations.go @@ -3,7 +3,6 @@ package itglue import ( "encoding/json" "fmt" - "net/url" ) //OrganizationData contains the schema of an Organization in IT Glue without the "data" wrapper. @@ -41,39 +40,39 @@ type OrganizationList struct { //GetOrganizationByID expects an ITG organization ID //Returns a pointer to an Organization struct func (itg *ITGAPI) GetOrganizationByID(organizationID int) (*Organization, error) { - itgurl, err := itg.BuildURL(fmt.Sprintf("/organizations/%d", organizationID)) + req := itg.NewRequest(fmt.Sprintf("/organizations/%d", organizationID), "GET", nil) + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build URL: %s", err) - } - body, err := itg.GetRequest(itgurl) - if err != nil { - return nil, fmt.Errorf("request failed: %s", err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } + organization := &Organization{} - err = json.Unmarshal(body, organization) + err = json.Unmarshal(req.Body, organization) if err != nil { return nil, fmt.Errorf("could not get organization: %s", err) } + return organization, nil } //GetOrganizationByName expects an exact matching organization name and returns an OrganizationList func (itg *ITGAPI) GetOrganizationByName(organizationName string) (*OrganizationList, error) { - itgurl, err := itg.BuildURL("/organizations") + req := itg.NewRequest("/organizations", "GET", nil) + req.URLValues.Add("filter[name]", organizationName) + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build URL: %s", err) - } - params := url.Values{} - params.Add("filter[name]", organizationName) - itgurl.RawQuery = params.Encode() - body, err := itg.GetRequest(itgurl) - if err != nil { - return nil, fmt.Errorf("request failed: %s", err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } + organization := &OrganizationList{} - err = json.Unmarshal(body, organization) + err = json.Unmarshal(req.Body, organization) if err != nil { return nil, fmt.Errorf("could not get organization: %s", err) } + + if len((*organization).Data) == 0 { + return nil, fmt.Errorf("ITG returned no results for %s", organizationName) + } + return organization, nil } diff --git a/itglue/user-metrics.go b/itglue/user-metrics.go index 0a8e936..48de986 100644 --- a/itglue/user-metrics.go +++ b/itglue/user-metrics.go @@ -33,18 +33,14 @@ type UserMetricList struct { } func (itg *ITGAPI) GetUserMetrics() (*UserMetricList, error) { - itgurl, err := itg.BuildURL("/user_metrics") + req := itg.NewRequest("/user_metrics", "GET", nil) + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build URL: %s", err) - } - body, err := itg.GetRequest(itgurl) - - if err != nil { - return nil, fmt.Errorf("request failed: %s", err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } userMetrics := &UserMetricList{} - err = json.Unmarshal(body, userMetrics) + err = json.Unmarshal(req.Body, userMetrics) if err != nil { return nil, fmt.Errorf("could not get users: %s", err) } diff --git a/itglue/users.go b/itglue/users.go index 41fbd03..a2e8c04 100644 --- a/itglue/users.go +++ b/itglue/users.go @@ -43,18 +43,14 @@ type UserList struct { } func (itg *ITGAPI) GetUsers() (*UserList, error) { - itgurl, err := itg.BuildURL("/users") + req := itg.NewRequest("/users", "GET", nil) + err := req.Do() if err != nil { - return nil, fmt.Errorf("could not build URL: %s", err) - } - body, err := itg.GetRequest(itgurl) - - if err != nil { - return nil, fmt.Errorf("request failed: %s", err) + return nil, fmt.Errorf("request failed for %s: %s", req.RestAction, err) } users := &UserList{} - err = json.Unmarshal(body, users) + err = json.Unmarshal(req.Body, users) if err != nil { return nil, fmt.Errorf("could not get users: %s", err) }