-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add initial support for reference tables (#196)
- Loading branch information
1 parent
5cce6a9
commit 2613a7a
Showing
20 changed files
with
1,053 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package rest | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"io" | ||
"strings" | ||
|
||
"net/http" | ||
) | ||
|
||
// Client implements our RESTful customer API | ||
type Client struct { | ||
endpoint string | ||
httpClient *http.Client | ||
} | ||
|
||
// do is a helper to run HTTP request for a JSON API | ||
func (c *Client) do(ctx context.Context, method string, path string, body map[string]interface{}, result interface{}) error { | ||
var ( | ||
endpoint = fmt.Sprintf("%s%s", c.endpoint, path) | ||
reqBody io.Reader | ||
) | ||
|
||
if body != nil { | ||
data, err := json.Marshal(body) | ||
if err != nil { | ||
return fmt.Errorf("failed to marshal request body: %w", err) | ||
} | ||
reqBody = bytes.NewBuffer(data) | ||
} | ||
|
||
req, err := http.NewRequestWithContext(ctx, method, endpoint, reqBody) | ||
if err != nil { | ||
return fmt.Errorf("failed to create request: %w", err) | ||
} | ||
|
||
req.Header.Set("Content-Type", "application/json") | ||
|
||
resp, err := c.httpClient.Do(req) | ||
if err != nil { | ||
return fmt.Errorf("request failed: %w", err) | ||
} | ||
|
||
defer resp.Body.Close() | ||
switch resp.StatusCode { | ||
case http.StatusOK: | ||
default: | ||
return fmt.Errorf(strings.ToLower(http.StatusText(resp.StatusCode))) | ||
} | ||
decoder := json.NewDecoder(resp.Body) | ||
if err := decoder.Decode(&result); err != nil { | ||
return fmt.Errorf("error decoding response: %w", err) | ||
} | ||
return nil | ||
} | ||
|
||
type errorResponse struct { | ||
Message string `json:"message"` | ||
} | ||
|
||
func responseWrapper(resp *http.Response, err error) (*http.Response, error) { | ||
if err != nil { | ||
return nil, err | ||
} | ||
if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { | ||
defer resp.Body.Close() | ||
var errResponse errorResponse | ||
if err := json.NewDecoder(resp.Body).Decode(&errResponse); err != nil { | ||
return nil, fmt.Errorf("got status code %d, but failed to decode error message: %w", resp.StatusCode, err) | ||
} | ||
return nil, ErrorWithStatusCode{StatusCode: resp.StatusCode, Err: errors.New(errResponse.Message)} | ||
} | ||
return resp, nil | ||
} | ||
|
||
func (c *Client) Post(path string, contentType string, body io.Reader) (*http.Response, error) { | ||
return responseWrapper(c.httpClient.Post(c.endpoint+path, contentType, body)) | ||
} | ||
|
||
func (c *Client) Get(path string) (*http.Response, error) { | ||
return responseWrapper(c.httpClient.Get(c.endpoint + path)) | ||
} | ||
|
||
func (c *Client) Put(path string, contentType string, body io.Reader) (*http.Response, error) { | ||
req, err := http.NewRequest("PUT", c.endpoint+path, body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
req.Header.Set("Content-Type", contentType) | ||
return responseWrapper(c.httpClient.Do(req)) | ||
} | ||
|
||
func (c *Client) Patch(path string, contentType string, body io.Reader) (*http.Response, error) { | ||
req, err := http.NewRequest("PATCH", c.endpoint+path, body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
req.Header.Set("Content-Type", contentType) | ||
return responseWrapper(c.httpClient.Do(req)) | ||
} | ||
|
||
func (c *Client) Delete(path string) (*http.Response, error) { | ||
req, err := http.NewRequest("DELETE", c.endpoint+path, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return responseWrapper(c.httpClient.Do(req)) | ||
} | ||
|
||
// New returns client to customer API | ||
func New(endpoint string, client *http.Client) *Client { | ||
return &Client{ | ||
endpoint: endpoint, | ||
httpClient: client, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package rest | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
) | ||
|
||
type ErrorWithStatusCode struct { | ||
StatusCode int | ||
Err error | ||
} | ||
|
||
func (e ErrorWithStatusCode) Error() string { | ||
return fmt.Sprintf("%s (%d): %s", http.StatusText(e.StatusCode), e.StatusCode, e.Err.Error()) | ||
} | ||
|
||
func HasStatusCode(err error, code int) bool { | ||
if err == nil { | ||
return false | ||
} | ||
if errWithStatusCode, ok := err.(ErrorWithStatusCode); ok { | ||
return errWithStatusCode.StatusCode == code | ||
} | ||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package customer | ||
package rest | ||
|
||
import ( | ||
"context" | ||
|
Oops, something went wrong.