diff --git a/apiclient/apiclient.go b/apiclient/apiclient.go index 2a74a7e..3de0e62 100644 --- a/apiclient/apiclient.go +++ b/apiclient/apiclient.go @@ -1,2 +1,85 @@ // Package apiclient provides the API client used by the web app package apiclient + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + + "git.agecem.com/agecem/bottin-ag/apiresponse" +) + +type APIClient struct { + Key string + Host string + Port int + Protocol string +} + +func New(key, host, protocol string, port int) APIClient { + return APIClient{ + Key: key, + Host: host, + Port: port, + Protocol: protocol, + } +} + +// Makes APIClient.Call() returning only an error. The Call data is put into the responder parameter's reference +func (a *APIClient) CallResponder(method, route string, requestBody io.Reader, useKey bool, responder apiresponse.Responder) error { + callResponse, err := a.Call(method, route, requestBody, useKey) + if err != nil { + return err + } + defer callResponse.Body.Close() + + body, err := io.ReadAll(callResponse.Body) + if err != nil { + return err + } + + err = json.Unmarshal(body, responder) + if err != nil { + return err + } + + return nil +} + +func (a *APIClient) Call(method, route string, requestBody io.Reader, useKey bool) (*http.Response, error) { + var response *http.Response + + endpoint := fmt.Sprintf("%s://%s:%d%s", + a.Protocol, a.Host, a.Port, route, + ) + + // Create client + client := &http.Client{} + + // Create request + request, err := http.NewRequest(method, endpoint, requestBody) + if err != nil { + return response, err + } + + if useKey { + if a.Key == "" { + return response, fmt.Errorf("Call to API required a key but none was provided. See --help for instructions on providing an API key.") + } + + request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Key)) + } + + if requestBody != nil { + request.Header.Add("Content-Type", "application/json") + } + + // Fetch Request + response, err = client.Do(request) + if err != nil { + return response, err + } + + return response, nil +} diff --git a/apiresponse/apiresponse.go b/apiresponse/apiresponse.go index 0508b64..2114a9b 100644 --- a/apiresponse/apiresponse.go +++ b/apiresponse/apiresponse.go @@ -8,6 +8,14 @@ type Response struct { StatusCode int } +type Responder interface { + Respond() Responder +} + +func (r Response) Respond() Responder { + return r +} + // HealthGET is the response type for `GET /v:version/health/ http/1.1` type HealthGET struct { Response