Files
services/currency/handler/currency.go
2021-06-15 20:35:40 +01:00

106 lines
2.8 KiB
Go

package handler
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"github.com/micro/micro/v3/service/errors"
"github.com/micro/micro/v3/service/logger"
pb "github.com/micro/services/currency/proto"
)
type Currency struct {
Api string
}
func (c *Currency) Rates(ctx context.Context, req *pb.RatesRequest, rsp *pb.RatesResponse) error {
if len(req.Code) == 0 {
return errors.BadRequest("currency.rates", "missing code")
}
if len(req.Code) != 3 {
return errors.BadRequest("currency.rates", "code is invalid")
}
resp, err := http.Get(c.Api + "/latest/" + req.Code)
if err != nil {
logger.Errorf("Failed to get rates: %v\n", err)
return errors.InternalServerError("currency.rates", "failed to get rates")
}
defer resp.Body.Close()
b, _ := ioutil.ReadAll(resp.Body)
if resp.StatusCode != 200 {
logger.Errorf("Failed to get rates (non 200): %d %v\n", resp.StatusCode, string(b))
return errors.InternalServerError("currency.rates", "failed to get rates")
}
var respBody map[string]interface{}
if err := json.Unmarshal(b, &respBody); err != nil {
logger.Errorf("Failed to unmarshal rates: %v\n", err)
return errors.InternalServerError("currency.rates", "failed to get rates")
}
rates, ok := respBody["conversion_rates"].(map[string]interface{})
if !ok {
logger.Errorf("Failed to convert rates to map[string]interface{}: %v\n", ok)
return errors.InternalServerError("currency.rates", "failed to get rates")
}
rsp.Code = req.Code
rsp.Rates = make(map[string]float64)
for code, rate := range rates {
rsp.Rates[code], _ = rate.(float64)
}
return nil
}
func (c *Currency) Convert(ctx context.Context, req *pb.ConvertRequest, rsp *pb.ConvertResponse) error {
if len(req.From) != 3 {
return errors.BadRequest("currency.convert", "invalid from code")
}
if len(req.To) != 3 {
return errors.BadRequest("currency.convert", "invalid to code")
}
uri := fmt.Sprintf("%s/pair/%s/%s", c.Api, req.From, req.To)
if req.Amount > 0.0 {
uri = fmt.Sprintf("%s/%v", uri, req.Amount)
}
resp, err := http.Get(uri)
if err != nil {
logger.Errorf("Failed to convert: %v\n", err)
return errors.InternalServerError("currency.convert", "failed to convert")
}
defer resp.Body.Close()
b, _ := ioutil.ReadAll(resp.Body)
if resp.StatusCode != 200 {
logger.Errorf("Failed to get convert (non 200): %d %v\n", resp.StatusCode, string(b))
return errors.InternalServerError("currency.convert", "failed to convert")
}
var respBody map[string]interface{}
if err := json.Unmarshal(b, &respBody); err != nil {
logger.Errorf("Failed to unmarshal conversion: %v\n", err)
return errors.InternalServerError("currency.convet", "failed to convert")
}
rsp.From = req.From
rsp.To = req.To
rsp.Rate, _ = respBody["conversion_rate"].(float64)
rsp.Amount, _ = respBody["conversion_result"].(float64)
return nil
}