Fetching currency rates in Go - part 5 talking to a microservice
In the previous part I implemented a simple microservice using micro in Go.
micro service
The server part of the code is almost straight out of the micro example code.
const (
dailyURL = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"
historicURL = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml"
)
func main() {
service := micro.NewService(
micro.Name("eurorate.server"),
micro.RegisterTTL(time.Minute),
micro.RegisterInterval(time.Second*30),
)
service.Init()
dailyProvider := parser.HTTPLiveProvider(dailyURL)
historicProvider := parser.HTTPHistoricProvider(historicURL)
proto.RegisterRatesHandler(service.Server(), handler.NewRatesHandler(dailyProvider, historicProvider))
if err := service.Run(); err != nil {
log.Fatal(err)
}
}
This exposes the handler through gRPC discoverable through whatever discoverable plugins micro exposes (by default consul).
Because this is a gRPC endpoint, we need a client to test this with…
micro client
Again, the code leans heavily on the micro example code, it uses the generated Protobuf file to create a service.
My test client looks remarkably similar…
package main
import (
"flag"
"fmt"
proto "github.com/bigkevmcd/euroxref/proto"
micro "github.com/micro/go-micro"
"golang.org/x/net/context"
)
func main() {
flag.Parse()
args := flag.Args()
service := micro.NewService(micro.Name("eurorate.client"))
client := proto.NewRatesClient("eurorate.server", service.Client())
rsp, err := client.Live(context.TODO(), &proto.LiveRequest{Currency: args[0]})
if err != nil {
fmt.Println(err)
}
fmt.Println(rsp.Rate)
}
This is pretty much straight out the micro example, but instantiates a
NewRatesClient
and then makes a call to fetch whatever currency is passed in
as an arg on the command-line.
I’ve mostly skipped over the use of contexts in this this code, and here’s a case where I could use a context with a timeout, but I’ll reserve contextising the code for a later part.
Running the client and server
At long last, after all this code, we I get to test the service, this will require a running consul running:
$ consul agent -dev
$ go run cmd/server/main.go
2018/02/09 07:52:45 Listening on [::]:63738
2018/02/09 07:52:45 Broker Listening on [::]:63739
2018/02/09 07:52:45 Registering node: eurorate.server-3716b902-0d6e-11e8-8bc3-ba0039b89401
$ go run cmd/client/main.go GBP
currency:"GBP" rate:"0.87513" referenceDate:"2018-02-08"
The average time taken to run the client is 0.203s
, but making 10 calls to
the server from a client takes around 0.526s
.
This is uncached…i.e. the server makes a request to the ECB for every request the client makes, which I’ll address in a future article.