Hello World

A hello world example using Go Micro

Overview

This is a helloworld example of using Go Micro. We’ll run through writing the whole thing.

Writing a service

Writing a service is incredibly simple with Go Micro. It provides you the framework to move fast without needing to understand everything at first. Below is a simple greeter service example that we’ll run through.

Find the full example code at examples/service.

Service Proto

One of the key requirements of microservices is strongly defined interfaces. Micro uses protobuf to achieve this.

Here we define the Greeter handler with the method Hello. It takes a Request and Response both with one string arguments.

  1. syntax = "proto3";
  2. service Greeter {
  3. rpc Hello(Request) returns (Response) {}
  4. }
  5. message Request {
  6. string name = 1;
  7. }
  8. message Response {
  9. string greeting = 2;
  10. }

Generate Proto

After writing the proto definition we must compile it using protoc with the micro plugin.

  1. protoc --proto_path=$GOPATH/src:. --micro_out=. --go_out=. path/to/greeter.proto

Implement Service

Now that we’ve defined the service interface we need to implement the service.

Below is the code for the greeter service. It does the following:

  • Implements the interface defined for the Greeter handler
  • Initialises a micro.Service
  • Registers the Greeter handler
  • Runs the service
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. micro "github.com/micro/go-micro/v2"
  6. proto "github.com/micro/examples/service/proto"
  7. )
  8. type Greeter struct{}
  9. func (g *Greeter) Hello(ctx context.Context, req *proto.Request, rsp *proto.Response) error {
  10. rsp.Greeting = "Hello " + req.Name
  11. return nil
  12. }
  13. func main() {
  14. // Create a new service. Optionally include some options here.
  15. service := micro.NewService(
  16. micro.Name("greeter"),
  17. )
  18. // Init will parse the command line flags.
  19. service.Init()
  20. // Register handler
  21. proto.RegisterGreeterHandler(service.Server(), new(Greeter))
  22. // Run the server
  23. if err := service.Run(); err != nil {
  24. fmt.Println(err)
  25. }
  26. }

Run Service

Now run the example using Go. If you’re working with the example code do the following:

  1. go run examples/service/main.go

This should output something like the folloing

  1. 2019-11-13 21:39:38.327452 I | Transport [http] Listening on [::]:32945
  2. 2019-11-13 21:39:38.327548 I | Broker [http] Connected to [::]:38955
  3. 2019-11-13 21:39:38.328095 I | Registry [mdns] Registering node: greeter-39373107-5ae7-42a2-b5e2-ebebf7eafbd9

Write Client

Once we’ve got a service we actually need a way to query it. This is at the heart of microservices as we not only serve but also consume other services. Below is the client code to query the greeter service.

The generated proto includes a greeter client to reduce boilerplate code.

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. micro "github.com/micro/go-micro/v2"
  6. proto "github.com/micro/examples/service/proto"
  7. )
  8. func main() {
  9. // Create a new service
  10. service := micro.NewService(micro.Name("greeter.client"))
  11. // Initialise the client and parse command line flags
  12. service.Init()
  13. // Create new greeter client
  14. greeter := proto.NewGreeterService("greeter", service.Client())
  15. // Call the greeter
  16. rsp, err := greeter.Hello(context.TODO(), &proto.Request{Name: "John"})
  17. if err != nil {
  18. fmt.Println(err)
  19. }
  20. // Print response
  21. fmt.Println(rsp.Greeting)
  22. }

Now run the client

  1. go run client.go

And the output should simply print the response

  1. Hello John