Files
services/address/handler/address.go
2021-08-27 13:36:41 +01:00

88 lines
2.3 KiB
Go

package handler
import (
"context"
"fmt"
"strings"
"github.com/micro/micro/v3/service/errors"
"github.com/micro/micro/v3/service/logger"
"github.com/micro/micro/v3/service/store"
pb "github.com/micro/services/address/proto"
"github.com/micro/services/pkg/api"
)
var (
AddressURL = "https://api.ideal-postcodes.co.uk/v1/"
)
type Address struct {
Url string
Key string
}
func field(key string, vals map[string]interface{}) string {
if v, ok := vals[key].(string); ok {
return v
}
return ""
}
func (a *Address) lookupPostcode(q string, rsp interface{}) error {
u := fmt.Sprintf("%saddresses?api_key=%s&postcode=%s", a.Url, a.Key, q)
return api.Get(u, rsp)
}
func (a *Address) LookupPostcode(ctx context.Context, req *pb.LookupPostcodeRequest, rsp *pb.LookupPostcodeResponse) error {
if len(req.Postcode) == 0 {
return errors.BadRequest("address.lookup-postcode", "missing postcode")
}
// check the store to see if we have it already
postcode := strings.ToLower(req.Postcode)
postcode = strings.ReplaceAll(postcode, " ", "")
// check the store
rec, err := store.Read(postcode)
if err == nil && len(rec) > 0 {
for _, r := range rec {
var records []*pb.Record
r.Decode(&records)
rsp.Addresses = records
}
return nil
}
var resp map[string]interface{}
// lookup the address api for the given postcode
if err := a.lookupPostcode(postcode, &resp); err != nil {
logger.Errorf("Failed to lookup postcode %v: %v", req.Postcode, err)
return errors.InternalServerError("address.lookup-postcode", "failed to lookup postcode")
}
result := resp["result"].(map[string]interface{})
hits := result["hits"].([]interface{})
for _, res := range hits {
addr := res.(map[string]interface{})
rsp.Addresses = append(rsp.Addresses, &pb.Record{
LineOne: field("line_1", addr),
LineTwo: field("line_2", addr),
Organisation: field("organisation_name", addr),
BuildingName: field("building_name", addr),
Premise: field("premise", addr),
Street: field("thoroughfare", addr),
Locality: field("dependent_locality", addr),
Town: field("post_town", addr),
County: field("county", addr),
Postcode: field("postcode", addr),
})
}
// cache the record if we haven't done so already
store.Write(store.NewRecord(postcode, rsp.Addresses))
return nil
}