今天继续总结关于micro api的其它用法。因为每个知识点基本类似,在这篇笔记中了event和meta做对比。本系列的笔记全部参考 Go Micro官方源码及博客 ,比较多,有兴趣的可以去研究。
首先实现我们的方法,这里需要注意的是,由于我们这使用的是事件订阅方法,因此实现的所有的共有方法都会被访问依次,私有方法将不会被访问,在Go张默认函数名首字母小写为私有方法,所以下面的process函数将不会被访问。
type Event struct { } func (e *Event) Process(ctx context.Context, event *proto.Event) error { log.Log("公有方法Process 收到事件,", event.Name) log.Log("公有方法Process 数据", event.Data) return nil } func (e *Event) Process2(ctx context.Context, event *proto.Event) error { log.Log("公有方法Process2 收到事件,", event.Name) log.Log("公有方法Process2 数据", event.Data) return nil } func (e *Event) process(ctx context.Context, event *proto.Event) error { log.Log("私有方法process,收到事件,", event.Name) log.Log("私有方法process,数据", event.Data) return nil }
现在我们启动测试一下
image
image
localhost:8080/user/login
image
使用meta*我们可以在服务端配置我们的请求信息,不再借助proto文件中的Resquet,现在让我们重新定义我们的api.proto文件
syntax = "proto3"; service Example { rpc Call(CallRequest) returns(CallResponse) {}; } service Foo { rpc Bar(EmptyRequest) returns(EmptyResponse) {}; } message CallRequest { string name = 1; } message CallResponse { string message = 2; } message EmptyRequest { } message EmptyResponse { }
使用protoc命令生成代码
protoc --go_out=. --micro_out=. proto/api.proto
编写我们的服务端,服务端和之前的例子相比没有什么需要改变的写法。
func (e *Example) Call(ctx context.Context, req *proto.CallRequest, rsp *proto.CallResponse) error { log.Print("Meta Example.Call接口收到请求") if len(req.Name) == 0 { return errors.BadRequest("go.micro.api.example", "no content") } rsp.Message = "Meta已经收到你的请求," + req.Name return nil } func (f *Foo) Bar(ctx context.Context, req *proto.EmptyRequest, rsp *proto.EmptyResponse) error { log.Print("Meta Foo.Bar接口收到请求") // noop return nil }
main函数中注册的逻辑发生了改变,如下我们可以看到,在注册的时候我们规定了相关的路由和请求,这里需要注意的是,rapi是导入的提供handler的一个包 rapi "github.com/micro/go-micro/api/handler/api"
proto.RegisterExampleHandler(service.Server(), new(Example), api.WithEndpoint(&api.Endpoint{ // 接口方法,一定要在proto接口中存在,不能是类的自有方法 Name: "Example.Call", // http请求路由,支持POSIX风格 Path: []string{"/example/call"}, // 支持的方法类型 Method: []string{"POST"}, Handler: rapi.Handler, })) // 注册Foo接口处理器 proto.RegisterFooHandler(service.Server(), new(Foo), api.WithEndpoint(&api.Endpoint{ Name: "Foo.Bar", Path: []string{"/foo/bar"}, Method: []string{"POST"}, Handler: rapi.Handler, }))
现在让我们启动一下
image
image
image
image
我们需要注意的请求foo/bar是我们没有携带任何body值,是因为被调用的方法参数里没有任何属性,如果你带上body,会产生下面的错误
image