summaryrefslogtreecommitdiff
path: root/golang/pkg/api
diff options
context:
space:
mode:
Diffstat (limited to 'golang/pkg/api')
-rw-r--r--golang/pkg/api/api.go83
1 files changed, 61 insertions, 22 deletions
diff --git a/golang/pkg/api/api.go b/golang/pkg/api/api.go
index 472d9e5..1975e2e 100644
--- a/golang/pkg/api/api.go
+++ b/golang/pkg/api/api.go
@@ -9,6 +9,7 @@ import (
"log/slog"
"net/http"
"net/url"
+ "strconv"
"time"
)
@@ -25,7 +26,13 @@ func (e *APIError) Error() string {
type APIMessage struct {
Data json.RawMessage `json:"data"`
Error *APIError `json:"error"`
- //meta
+ Meta *Meta `json:"meta"`
+}
+
+type Meta struct {
+ Limit int `json:"limit"`
+ Page int `json:"page"`
+ Total int `json:"total"`
}
type Request struct {
@@ -45,30 +52,62 @@ type Response struct {
func (c *Client) Send(method string, uriRef *url.URL, payload any, response any) error {
responseChannel := make(chan *Response)
- c.requestsChannel <- &Request{
- method: method,
- payload: payload,
- priority: 10,
- responseChannel: responseChannel,
- uri: c.baseURI.ResolveReference(uriRef),
- }
- res := <-responseChannel
- if res.Err != nil {
- return res.Err
- }
- err := res.Message.Error
- if err != nil {
- switch err.Code {
- case 4214:
- e := decodeShipInTransitError(err.Data)
- time.Sleep(e.SecondsToArrival.Duration() * time.Second)
- return c.Send(method, uriRef, payload, response)
- default:
+ uri := c.baseURI.ResolveReference(uriRef)
+ query := uri.Query()
+ query.Add("limit", "20")
+ page := 1
+ var rawResponses []json.RawMessage
+ for {
+ query.Set("page", strconv.Itoa(page))
+ uri.RawQuery = query.Encode()
+ c.requestsChannel <- &Request{
+ method: method,
+ payload: payload,
+ priority: 10,
+ responseChannel: responseChannel,
+ uri: uri,
+ }
+ res := <-responseChannel
+ if res.Err != nil {
+ return res.Err
+ }
+ if err := res.Message.Error; err != nil {
return err
}
+ err := res.Message.Error
+ if err != nil {
+ switch err.Code {
+ case 4214:
+ e := decodeShipInTransitError(err.Data)
+ time.Sleep(e.SecondsToArrival.Duration() * time.Second)
+ return c.Send(method, uriRef, payload, response)
+ default:
+ return err
+ }
+ }
+ if res.Message.Meta == nil {
+ // This is not a paginated request, we are done
+ if err := json.Unmarshal(res.Message.Data, &response); err != nil {
+ return fmt.Errorf("failed to unmarshal message: %w", err)
+ }
+ return nil
+ }
+ var oneResponse []json.RawMessage
+ if err := json.Unmarshal(res.Message.Data, &oneResponse); err != nil {
+ return fmt.Errorf("failed to unmarshal message: %w", err)
+ }
+ rawResponses = append(rawResponses, oneResponse...)
+ if res.Message.Meta.Limit*res.Message.Meta.Page >= res.Message.Meta.Total {
+ break
+ }
+ page++
+ }
+ responses, err := json.Marshal(rawResponses)
+ if err != nil {
+ return fmt.Errorf("failed to marshal raw responses to paginated request: %w", err)
}
- if err := json.Unmarshal(res.Message.Data, &response); err != nil {
- return fmt.Errorf("failed to unmarshal message: %w", err)
+ if err := json.Unmarshal(responses, &response); err != nil {
+ return fmt.Errorf("failed to unmarshal paginated request responses: %w", err)
}
return nil
}