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.