Added error handling
This commit is contained in:
parent
3440d00924
commit
cff418c0ff
3
.gitignore
vendored
3
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
example/main.go
|
example/main.go
|
||||||
|
.vscode/tasks.json
|
||||||
|
@ -4,15 +4,18 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
func check(err error) {
|
type Metadata struct {
|
||||||
if err != nil {
|
CurrentPage int `json:"current-page"`
|
||||||
log.Fatal(err)
|
NextPage interface{} `json:"next-page"`
|
||||||
}
|
PrevPage interface{} `json:"prev-page"`
|
||||||
|
TotalPages int `json:"total-pages"`
|
||||||
|
TotalCount int `json:"total-count"`
|
||||||
|
Filters struct {
|
||||||
|
} `json:"filters"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//ITGAPI contains the ITG API URL for North America, as well as the API key.
|
//ITGAPI contains the ITG API URL for North America, as well as the API key.
|
||||||
@ -28,43 +31,48 @@ func NewITGAPI(apiKey string) *ITGAPI {
|
|||||||
return &ITGAPI{Site: "https://api.itglue.com", APIKey: apiKey}
|
return &ITGAPI{Site: "https://api.itglue.com", APIKey: apiKey}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHTTPResponseBody(resp *http.Response) []byte {
|
func getHTTPResponseBody(resp *http.Response) ([]byte, error) {
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("ITG returned HTTP status code %s\n%s", resp.Status, resp.Body)
|
||||||
out := fmt.Sprintf("ITG returned HTTP status code %s\n%s", resp.Status, resp.Body)
|
|
||||||
log.Fatal(out)
|
|
||||||
return make([]byte, 0) //TBD: Don't hack
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
check(err)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not read http response body: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
return body
|
return body, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//BuildURL expects a restaction to be passed to it
|
//BuildURL expects a restaction to be passed to it
|
||||||
//Returns the full request URL containing the ITG API domain prepended to the rest action
|
//Returns the full request URL containing the ITG API domain prepended to the rest action
|
||||||
func (itg *ITGAPI) BuildURL(restAction string) *url.URL {
|
func (itg *ITGAPI) BuildURL(restAction string) (*url.URL, error) {
|
||||||
var itgurl *url.URL
|
var itgurl *url.URL
|
||||||
itgurl, err := url.Parse(itg.Site)
|
itgurl, err := url.Parse(itg.Site)
|
||||||
check(err)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not parse url %s: %s", itg.Site, err)
|
||||||
|
}
|
||||||
itgurl.Path += restAction
|
itgurl.Path += restAction
|
||||||
return itgurl
|
return itgurl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetRequest allows a custom GET request to the API to be made.
|
//GetRequest allows a custom GET request to the API to be made.
|
||||||
//Also used internally by this package by the binding functions
|
//Also used internally by this package by the binding functions
|
||||||
//Expects URL to be passed
|
//Expects URL to be passed
|
||||||
//Returns the response body as a byte slice
|
//Returns the response body as a byte slice
|
||||||
func (itg *ITGAPI) GetRequest(itgurl *url.URL) []byte {
|
func (itg *ITGAPI) GetRequest(itgurl *url.URL) ([]byte, error) {
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
req, err := http.NewRequest("GET", itgurl.String(), nil)
|
req, err := http.NewRequest("GET", itgurl.String(), nil)
|
||||||
check(err)
|
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("Content-Type", "application/vnd.api+json")
|
||||||
req.Header.Set("x-api-key", itg.APIKey)
|
req.Header.Set("x-api-key", itg.APIKey)
|
||||||
req.Header.Set("cache-control", "no-cache")
|
req.Header.Set("cache-control", "no-cache")
|
||||||
response, err := client.Do(req)
|
response, err := client.Do(req)
|
||||||
check(err)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("http request failed: %s", err)
|
||||||
|
}
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
|
|
||||||
return getHTTPResponseBody(response)
|
return getHTTPResponseBody(response)
|
||||||
@ -74,15 +82,19 @@ func (itg *ITGAPI) GetRequest(itgurl *url.URL) []byte {
|
|||||||
//Also used internally by this package by the binding functions
|
//Also used internally by this package by the binding functions
|
||||||
//Expects a URL and a body to be passed
|
//Expects a URL and a body to be passed
|
||||||
//Returns the response body as a byte slice
|
//Returns the response body as a byte slice
|
||||||
func (itg *ITGAPI) PostRequest(itgurl *url.URL, body io.Reader) []byte {
|
func (itg *ITGAPI) PostRequest(itgurl *url.URL, body io.Reader) ([]byte, error) {
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
req, err := http.NewRequest("POST", itgurl.String(), body)
|
req, err := http.NewRequest("POST", itgurl.String(), body)
|
||||||
check(err)
|
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("Content-Type", "application/vnd.api+json")
|
||||||
req.Header.Set("x-api-key", itg.APIKey)
|
req.Header.Set("x-api-key", itg.APIKey)
|
||||||
req.Header.Set("cache-control", "no-cache")
|
req.Header.Set("cache-control", "no-cache")
|
||||||
response, err := client.Do(req)
|
response, err := client.Do(req)
|
||||||
check(err)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("http request failed: %s", err)
|
||||||
|
}
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
|
|
||||||
return getHTTPResponseBody(response)
|
return getHTTPResponseBody(response)
|
||||||
@ -93,15 +105,19 @@ func (itg *ITGAPI) PostRequest(itgurl *url.URL, body io.Reader) []byte {
|
|||||||
//Also used internally by this package by the binding functions
|
//Also used internally by this package by the binding functions
|
||||||
//Expects a URL and a body to be passed
|
//Expects a URL and a body to be passed
|
||||||
//Returns the response body as a byte slice
|
//Returns the response body as a byte slice
|
||||||
func (itg *ITGAPI) PatchRequest(itgurl *url.URL, body io.Reader) []byte {
|
func (itg *ITGAPI) PatchRequest(itgurl *url.URL, body io.Reader) ([]byte, error) {
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
req, err := http.NewRequest("PATCH", itgurl.String(), body)
|
req, err := http.NewRequest("PATCH", itgurl.String(), body)
|
||||||
check(err)
|
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("Content-Type", "application/vnd.api+json")
|
||||||
req.Header.Set("x-api-key", itg.APIKey)
|
req.Header.Set("x-api-key", itg.APIKey)
|
||||||
req.Header.Set("cache-control", "no-cache")
|
req.Header.Set("cache-control", "no-cache")
|
||||||
response, err := client.Do(req)
|
response, err := client.Do(req)
|
||||||
check(err)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("http request failed: %s", err)
|
||||||
|
}
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
|
|
||||||
return getHTTPResponseBody(response)
|
return getHTTPResponseBody(response)
|
||||||
|
@ -4,8 +4,32 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type OrganizationTypeData struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Attributes struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
CreatedAt time.Time `json:"created-at"`
|
||||||
|
UpdatedAt time.Time `json:"updated-at"`
|
||||||
|
Synced bool `json:"synced"`
|
||||||
|
} `json:"attributes"`
|
||||||
|
|
||||||
|
Meta struct {
|
||||||
|
CurrentPage int `json:"current-page"`
|
||||||
|
NextPage interface{} `json:"next-page"`
|
||||||
|
PrevPage interface{} `json:"prev-page"`
|
||||||
|
TotalPages int `json:"total-pages"`
|
||||||
|
TotalCount int `json:"total-count"`
|
||||||
|
Filters struct {
|
||||||
|
} `json:"filters"`
|
||||||
|
} `json:"meta"`
|
||||||
|
Links struct {
|
||||||
|
} `json:"links"`
|
||||||
|
}
|
||||||
|
|
||||||
//OrganizationInternalData contains the schema of an Organization in IT Glue without the "data" wrapper.
|
//OrganizationInternalData contains the schema of an Organization in IT Glue without the "data" wrapper.
|
||||||
//This allows us to reuse the schema when data is either a JSON object or an array, depending on what results are returned
|
//This allows us to reuse the schema when data is either a JSON object or an array, depending on what results are returned
|
||||||
type OrganizationInternalData struct {
|
type OrganizationInternalData struct {
|
||||||
@ -36,13 +60,40 @@ type OrganizationList struct {
|
|||||||
Data []struct{ OrganizationInternalData } `json:"data"`
|
Data []struct{ OrganizationInternalData } `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///organization_types
|
||||||
|
func (itg *ITGAPI) GetOrganizationTypes() error {
|
||||||
|
itgurl, err := itg.BuildURL("/organization_types")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not build URL: %s", err)
|
||||||
|
}
|
||||||
|
body, err := itg.GetRequest(itgurl)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("request failed: %s", err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(body))
|
||||||
|
|
||||||
|
/*organization := &Organization{}
|
||||||
|
err := json.Unmarshal(body, organization)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not get organization: %s", err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
//GetOrganizationByID expects an ITG organization ID
|
//GetOrganizationByID expects an ITG organization ID
|
||||||
//Returns a pointer to an Organization struct
|
//Returns a pointer to an Organization struct
|
||||||
func (itg *ITGAPI) GetOrganizationByID(organizationID int) (*Organization, error) {
|
func (itg *ITGAPI) GetOrganizationByID(organizationID int) (*Organization, error) {
|
||||||
itgurl := itg.BuildURL(fmt.Sprintf("/organizations/%d", organizationID))
|
itgurl, err := itg.BuildURL(fmt.Sprintf("/organizations/%d", organizationID))
|
||||||
body := itg.GetRequest(itgurl)
|
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)
|
||||||
|
}
|
||||||
organization := &Organization{}
|
organization := &Organization{}
|
||||||
err := json.Unmarshal(body, organization)
|
err = json.Unmarshal(body, organization)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not get organization: %s", err)
|
return nil, fmt.Errorf("could not get organization: %s", err)
|
||||||
}
|
}
|
||||||
@ -51,13 +102,19 @@ func (itg *ITGAPI) GetOrganizationByID(organizationID int) (*Organization, error
|
|||||||
|
|
||||||
//GetOrganizationByName expects an exact matching organization name and returns an OrganizationList
|
//GetOrganizationByName expects an exact matching organization name and returns an OrganizationList
|
||||||
func (itg *ITGAPI) GetOrganizationByName(organizationName string) (*OrganizationList, error) {
|
func (itg *ITGAPI) GetOrganizationByName(organizationName string) (*OrganizationList, error) {
|
||||||
itgurl := itg.BuildURL("/organizations")
|
itgurl, err := itg.BuildURL("/organizations")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not build URL: %s", err)
|
||||||
|
}
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("filter[name]", organizationName)
|
params.Add("filter[name]", organizationName)
|
||||||
itgurl.RawQuery = params.Encode()
|
itgurl.RawQuery = params.Encode()
|
||||||
body := itg.GetRequest(itgurl)
|
body, err := itg.GetRequest(itgurl)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("request failed: %s", err)
|
||||||
|
}
|
||||||
organization := &OrganizationList{}
|
organization := &OrganizationList{}
|
||||||
err := json.Unmarshal(body, organization)
|
err = json.Unmarshal(body, organization)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not get organization: %s", err)
|
return nil, fmt.Errorf("could not get organization: %s", err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user