From 1e22145ef92efb097ef87e8f6a1748c98dbd05f9 Mon Sep 17 00:00:00 2001 From: Lucas Fonseca Date: Tue, 5 Nov 2024 13:37:29 +0000 Subject: [PATCH] feat: add geocode request to postcodes.io client --- lib/postcodesio/client.go | 36 ++++++++++++++++++++++++++++++++++ lib/postcodesio/client_test.go | 19 ++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/lib/postcodesio/client.go b/lib/postcodesio/client.go index 488e3e8..9fd0777 100644 --- a/lib/postcodesio/client.go +++ b/lib/postcodesio/client.go @@ -29,6 +29,7 @@ const DefaultBaseURL = "https://api.postcodes.io" // Service interface contains all available, exposed methods of postcodes.io type Service interface { + Geocode(ctx context.Context, postcode string) (*Postcode, error) ReverseGeocode(ctx context.Context, latitude, longitude float64) (*Postcode, error) } @@ -93,6 +94,20 @@ func (c *Client) ReverseGeocode(ctx context.Context, latitude, longitude float64 return res.Result[0], nil } +func (c *Client) Geocode(ctx context.Context, postcode string) (*Postcode, error) { + var res struct { + Status int `json:"status"` + Result *Postcode `json:"result"` + } + + err := c.Do(ctx, "GET", "/postcodes/"+postcode, nil, nil, &res) + if err != nil { + return nil, err + } + + return res.Result, nil +} + // ReverseGeocode returns a set (or no) postcodes that exist within a long/lat func (fc *FailoverClient) ReverseGeocode(ctx context.Context, latitude, longitude float64) (*Postcode, error) { var errors []cher.E @@ -116,6 +131,27 @@ func (fc *FailoverClient) ReverseGeocode(ctx context.Context, latitude, longitud }, errors...) } +func (fc *FailoverClient) Geocode(ctx context.Context, postcode string) (*Postcode, error) { + var errors []cher.E + + for _, cli := range fc.clients { + pc, err := cli.Geocode(ctx, postcode) + if err == nil { + return pc, nil + } + + cErr := cher.New("postcodes_request_failed", cher.M{ + "message": err.Error(), + }) + + errors = append(errors, cErr) + } + + return nil, cher.New("postcode_error", cher.M{ + "postcode": postcode, + }, errors...) +} + // interface guards var ( _ Service = (*Client)(nil) diff --git a/lib/postcodesio/client_test.go b/lib/postcodesio/client_test.go index 0af8dcc..0f9c5a1 100644 --- a/lib/postcodesio/client_test.go +++ b/lib/postcodesio/client_test.go @@ -30,3 +30,22 @@ func TestFallbackReverseGeocode(t *testing.T) { t.Error(errors.New("no response when one expected")) } } + +func TestFailoverClient_Geocode(t *testing.T) { + std := postcodesio.New(postcodesio.DefaultBaseURL + "breakthisurl") + fallback := postcodesio.New(postcodesio.DefaultBaseURL) + + fallbackClient, err := postcodesio.NewFailoverClient(std, fallback) + if err != nil { + t.Error(err) + } + + pc, err := fallbackClient.Geocode(context.Background(), "N1 1AA") + if err != nil { + t.Error(err) + } + + if pc == nil { + t.Error(errors.New("no response when one expected")) + } +}