151 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# Code Generation [Experimental]
 | 
						|
 | 
						|
We're experimenting with code generation to reduce the amount of boiler plate code written.
 | 
						|
 | 
						|
## Example
 | 
						|
 | 
						|
Going from this
 | 
						|
```golang
 | 
						|
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
 | 
						|
 | 
						|
```golang
 | 
						|
rsp, err := cl.Call(context.Background(), &example.Request{Name: "John"})
 | 
						|
if err != nil {
 | 
						|
	return err
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
## Generation of stub code for the example service
 | 
						|
 | 
						|
```shell
 | 
						|
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
 | 
						|
 | 
						|
```shell
 | 
						|
go get github.com/micro/protobuf/protoc-gen-go
 | 
						|
```
 | 
						|
 | 
						|
### Define your proto service.
 | 
						|
 | 
						|
hello.proto
 | 
						|
```shell
 | 
						|
syntax = "proto3";
 | 
						|
 | 
						|
// package name is used as the service name for discovery
 | 
						|
// if service name is not passed in when initialising the 
 | 
						|
// client
 | 
						|
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
 | 
						|
 | 
						|
```shell
 | 
						|
protoc --go_out=plugins=micro:. hello.proto
 | 
						|
```
 | 
						|
 | 
						|
### Generated code
 | 
						|
 | 
						|
```shell
 | 
						|
// Client API for Say service
 | 
						|
 | 
						|
type SayClient interface {
 | 
						|
        Hello(ctx context.Context, in *Request) (*Response, error)
 | 
						|
}
 | 
						|
 | 
						|
type sayClient struct {
 | 
						|
        c           client.Client
 | 
						|
        serviceName string
 | 
						|
}
 | 
						|
 | 
						|
func NewSayClient(serviceName string, c client.Client) SayClient {
 | 
						|
        if c == nil {
 | 
						|
                c = client.NewClient()
 | 
						|
        }
 | 
						|
        if len(serviceName) == 0 {
 | 
						|
                serviceName = "go.micro.srv.greeter"
 | 
						|
        }
 | 
						|
        return &sayClient{
 | 
						|
                c:           c,
 | 
						|
                serviceName: serviceName,
 | 
						|
        }
 | 
						|
}
 | 
						|
 | 
						|
func (c *sayClient) Hello(ctx context.Context, in *Request) (*Response, error) {
 | 
						|
        req := c.c.NewRequest(c.serviceName, "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 SayHandler interface {
 | 
						|
        Hello(context.Context, *Request, *Response) error
 | 
						|
}
 | 
						|
 | 
						|
func RegisterSayHandler(s server.Server, hdlr SayHandler) {
 | 
						|
        s.Handle(s.NewHandler(hdlr))
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
### Use the client
 | 
						|
```golang
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
 | 
						|
	"golang.org/x/net/context"
 | 
						|
	"github.com/micro/go-micro/client"
 | 
						|
	hello "path/to/hello/proto"
 | 
						|
)
 | 
						|
 | 
						|
func main() {
 | 
						|
	cl := hello.NewSayClient("go.micro.srv.greeter", client.DefaultClient)
 | 
						|
	// alternative initialisation
 | 
						|
	// cl := hello.NewSayClient("", nil)
 | 
						|
 | 
						|
	rsp, err := cl.Hello(contex.Background(), &hello.Request{"Name": "John"})
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
	}
 | 
						|
}
 | 
						|
```
 |