2015-12-02 23:09:48 +00:00
..
2015-12-02 22:44:01 +00:00
2015-12-02 23:09:48 +00:00

Code Generation [Experimental]

We're experimenting with code generation to reduce the amount of boiler plate code written.

Example

Going from this

req := client.NewRequest("go.micro.srv.example", "Example.Call", &example.Request{
	Name: "John",
})

rsp := &example.Response{}

if err := client.Call(context.Background(), req, rsp); err != nil {
	return err
}

To

rsp, err := cl.Call(context.Background(), &example.Request{Name: "John"})
if err != nil {
	return err
}

Generation of stub code for the example service

go get github.com/micro/protobuf/protoc-gen-go
cd examples/server/proto/example
protoc --go_out=plugins=micro:. example.proto

Look at examples/server/proto/example/example.pb.go to see the generated code.

Guide

Download the protoc-gen-go code

go get github.com/micro/protobuf/protoc-gen-go

Define your proto service.

greeter.proto

syntax = "proto3";

// package name is used as the service name for discovery
package go.micro.srv.greeter;

service Say {
	rpc Hello(Request) returns (Response) {}
}

message Request {
	optional string name = 1;
}

message Response {
	optional string msg = 1;
}

Note: Remember to set package name in the proto, it's used to generate the service for discovery.

Generate code

protoc --go_out=plugins=micro:. hello.proto

Generated code

// Client API for Say service

type SayClient interface {
	Hello(ctx context.Context, in *Request) (*Response, error)
}

type sayClient struct {
	c client.Client
}

func NewSayClient(c client.Client) SayClient {
	if c == nil {
		c = client.NewClient()
	}
	return &sayClient{
		c: c,
	}
}

func (c *sayClient) Hello(ctx context.Context, in *Request) (*Response, error) {
	req := c.c.NewRequest("go.micro.srv.greeter", "Say.Hello", in)
	out := new(Response)
	err := c.c.Call(ctx, req, out)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// Server API for Say service

type SayServer interface {
	Hello(context.Context, *Request, *Response) error
}

func RegisterSayServer(s server.Server, srv SayServer) {
	s.Handle(s.NewHandler(srv))
}

Use the client


import (
	"fmt"

	"golang.org/x/net/context"
	"github.com/micro/go-micro/client"
	hello "path/to/hello/proto"
)

func main() {
	cl := hello.NewSayClient(client.DefaultClient)

	rsp, err := cl.Hello(contex.Background(), &hello.Request{"Name": "John"})
	if err != nil {
		fmt.Println(err)
	}
}