package handler import ( "context" "encoding/json" "io/ioutil" "net/http" "github.com/micro/micro/v3/service/errors" "github.com/micro/micro/v3/service/logger" pb "github.com/micro/services/postcode/proto" ) var ( PostcodeAPI = "https://api.postcodes.io/postcodes/" RandomPostcodeURL = "https://api.postcodes.io/random/postcodes" ) type Postcode struct{} func (e *Postcode) Lookup(ctx context.Context, req *pb.LookupRequest, rsp *pb.LookupResponse) error { if len(req.Postcode) == 0 { return errors.BadRequest("postcode.lookup", "missing postcode") } resp, err := http.Get(PostcodeAPI + req.Postcode) if err != nil { logger.Errorf("Failed to http call %v: %v", PostcodeAPI+req.Postcode, err.Error()) return errors.BadRequest("postcode.lookup", "failed to lookup postcode") } defer resp.Body.Close() b, _ := ioutil.ReadAll(resp.Body) if resp.StatusCode != 200 { logger.Errorf("Failed to http call (%v) %v: %v", resp.StatusCode, PostcodeAPI+req.Postcode, string(b)) return errors.BadRequest("postcode.lookup", "failed to lookup postcode") } var response map[string]interface{} if err := json.Unmarshal(b, &response); err != nil { logger.Error("Failed to unmarshal %v: %v", PostcodeAPI+req.Postcode, err.Error()) return errors.BadRequest("postcode.lookup", "failed to lookup postcode") } result := response["result"].(map[string]interface{}) rsp.Postcode = result["postcode"].(string) rsp.Country = result["country"].(string) rsp.Region = result["region"].(string) rsp.Latitude = result["latitude"].(float64) rsp.Longitude = result["longitude"].(float64) rsp.District = result["admin_district"].(string) rsp.Ward = result["admin_ward"].(string) return nil } func (e *Postcode) Validate(ctx context.Context, req *pb.ValidateRequest, rsp *pb.ValidateResponse) error { if len(req.Postcode) == 0 { return errors.BadRequest("postcode.validate", "missing postcode") } resp, err := http.Get(PostcodeAPI + req.Postcode + "/validate") if err != nil { logger.Errorf("Failed to http call %v: %v", PostcodeAPI+req.Postcode+"/validate", err.Error()) return errors.BadRequest("postcode.validate", "failed to validate postcode") } defer resp.Body.Close() b, _ := ioutil.ReadAll(resp.Body) if resp.StatusCode != 200 { logger.Errorf("Failed to http call (%v) %v: %v", resp.StatusCode, PostcodeAPI+req.Postcode+"/validate", string(b)) return errors.BadRequest("postcode.validate", "failed to validate postcode") } var response map[string]interface{} if err := json.Unmarshal(b, &response); err != nil { logger.Error("Failed to unmarshal %v: %v", PostcodeAPI+req.Postcode+"/validate", err.Error()) return errors.BadRequest("postcode.validate", "failed to validate postcode") } result := response["result"].(bool) rsp.Valid = result return nil } func (e *Postcode) Random(ctx context.Context, req *pb.RandomRequest, rsp *pb.RandomResponse) error { resp, err := http.Get(RandomPostcodeURL) if err != nil { logger.Errorf("Failed to http call %v: %v", RandomPostcodeURL, err.Error()) return errors.BadRequest("postcode.random", "failed to lookup random postcode") } defer resp.Body.Close() b, _ := ioutil.ReadAll(resp.Body) if resp.StatusCode != 200 { logger.Errorf("Failed to http call (%v) %v: %v", resp.StatusCode, RandomPostcodeURL, string(b)) return errors.BadRequest("postcode.random", "failed to lookup rabdom postcode") } var response map[string]interface{} if err := json.Unmarshal(b, &response); err != nil { logger.Error("Failed to unmarshal %v: %v", RandomPostcodeURL, err.Error()) return errors.BadRequest("postcode.random", "failed to lookup random postcode") } result := response["result"].(map[string]interface{}) rsp.Postcode = result["postcode"].(string) rsp.Country = result["country"].(string) rsp.Region = result["region"].(string) rsp.Latitude = result["latitude"].(float64) rsp.Longitude = result["longitude"].(float64) rsp.District = result["admin_district"].(string) rsp.Ward = result["admin_ward"].(string) return nil }