Copyright © 2022-2024 aizws.net · 网站版本: v1.2.6·内部版本: v1.23.3·
页面加载耗时 0.00 毫秒·物理内存 61.2MB ·虚拟内存 1300.0MB
欢迎来到 AI 中文社区(简称 AI 中文社),这里是学习交流 AI 人工智能技术的中文社区。 为了更好的体验,本站推荐使用 Chrome 浏览器。
Go Micro API 服务是对 SRV RPC服务的封装,它将请求装换为 RPC 请求转给 SRV RPC 服务,并将 SRV RPC 的处理结果返回客户端。
我们可以使用 Go Micro 的 micro 工具创建 API 服务。例如,创建 hello API 服务:
micro new --type=api hello
以下是 micro 创建的 API 服务的文件结构:
. ├── main.go ├── generate.go ├── plugin.go ├── client │ └── hello.go ├── handler │ └── hello.go ├── proto/hello │ └── hello.proto ├── Makefile ├── Dockerfile └── README.md
package main import ( "github.com/micro/go-micro/util/log" "github.com/micro/go-micro" "hello/handler" "hello/client" hello "hello/proto/hello" ) func main() { // 创建一个新的服务,服务名为 go.micro.api.hello service := micro.NewService( micro.Name("go.micro.api.hello"), micro.Version("latest"), ) // 通过命令行参数或者插件初始化服务 service.Init( // 为 hello srv客户端创建封装 wrap。 micro.WrapHandler(client.HelloWrapper(service)), ) // 注册业务处理组件 handler.Hello hello.RegisterHelloHandler(service.Server(), new(handler.Hello)) // 运行服务 if err := service.Run(); err != nil { log.Fatal(err) } }
syntax = "proto3"; package go.micro.api.hello; option go_package="proto/hello"; service Hello { rpc Call(Request) returns (Response) {} } message Request { string name = 1; } message Response { string msg = 1; }
执行 make 命令进行编译:
make proto
编译后生成 proto/hello/hello.pb.micro.go 和 proto/hello/hello.pb.go 文件。
package handler import ( "context" "github.com/micro/go-micro/util/log" api "github.com/micro/go-micro/api/proto" "github.com/micro/go-micro/errors" "hello/client" "hello/proto/hello" ) type Hello struct{} func extractValue(pair *api.Pair) string { if pair == nil { return "" } if len(pair.Values) == 0 { return "" } return pair.Values[0] } // Hello.Call is called by the API as /hello/call with post body {"name": "foo"} func (e *Hello) Call(ctx context.Context, req *hello.Request, rsp *hello.Response) error { log.Log("Received Hello.Call request") // extract the client from the context helloClient, ok := client.HelloFromContext(ctx) if !ok { return errors.InternalServerError("go.micro.api.hello.hello.call", "hello client not found") } // make request response, err := helloClient.Call(ctx, &hello.Request{ Name: req.Name, }) if err != nil { return errors.InternalServerError("go.micro.api.hello.hello.call", err.Error()) } rsp.Msg = response.Msg return nil }
package client import ( "context" "github.com/micro/go-micro" "github.com/micro/go-micro/server" hello "hello/proto/hello" ) type helloKey struct {} // FromContext retrieves the client from the Context func HelloFromContext(ctx context.Context) (hello.HelloService, bool) { c, ok := ctx.Value(helloKey{}).(hello.HelloService) return c, ok } // Client returns a wrapper for the HelloClient func HelloWrapper(service micro.Service) server.HandlerWrapper { client := hello.NewHelloService("go.micro.srv.hello", service.Client()) return func(fn server.HandlerFunc) server.HandlerFunc { return func(ctx context.Context, req server.Request, rsp interface{}) error { ctx = context.WithValue(ctx, helloKey{}, client) return fn(ctx, req, rsp) } } }
make build
编译后生成可执行文件 hello_api,运行 hello_api。
nohup micro & ./hello_api
直接在浏览器中,输入 http://localhost:8080/hello.call。输出结果为:
{"msg":"success"}
Go Micro 插件 plugin:Go Micro plugin 会在每次调用服务的都会触发,根据注册的顺序进行调用,它的作用可以理解为拦截器。可以利用 plugin 实现拦截功能,比如鉴权,可结合 jwt 来实现。以下代码 plugi ...