From d88df70726ccda69405153203196c51406eef572 Mon Sep 17 00:00:00 2001 From: "suguo.yao" Date: Sat, 7 Sep 2024 20:40:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=9F=BA=E4=BA=8Eprotobuf?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E7=9A=84api=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E9=9B=8F=E5=BD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- .vscode/launch.json | 2 +- Makefile | 9 +- go.mod | 1 + go.sum | 2 + handler/hello-handler.go | 22 +++ model/hello.pb.go | 277 ++++++++++++++++++++++++++++++++ model/hello.pb.micro.go | 15 ++ model/proto/hello.proto | 18 +++ readme.md | 11 +- webClient.go => webClient.go1 | 0 webClient2.go | 46 ++++++ webService.go => webService.go1 | 0 webService2.go | 36 +++++ 14 files changed, 436 insertions(+), 6 deletions(-) create mode 100644 model/hello.pb.go create mode 100644 model/hello.pb.micro.go create mode 100644 model/proto/hello.proto rename webClient.go => webClient.go1 (100%) create mode 100644 webClient2.go rename webService.go => webService.go1 (100%) create mode 100644 webService2.go diff --git a/.gitignore b/.gitignore index 8f58478..6666dde 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ go-micro-demo *.exe go.sum -webservice \ No newline at end of file +webservice +.vscode/ \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index ea65dfd..c7e476a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,7 @@ "type": "go", "request": "launch", "mode": "auto", - "program": "/home/suguo/project/go-micro-demo/webClient.go" + "program": "/home/suguo/project/go-micro-demo/webService2.go" } ] } \ No newline at end of file diff --git a/Makefile b/Makefile index 69ae2d0..07d253f 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,7 @@ -.PHONY : run -dev : +.PHONY: dev +dev: + go run . - go run . \ No newline at end of file +.PHONY: generate +generate: + protoc --proto_path=. proto/hello.proto --go_out=. --micro_out=. \ No newline at end of file diff --git a/go.mod b/go.mod index 2b8f78b..9a3b8d5 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,7 @@ require ( github.com/cloudwego/iasm v0.2.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/fatih/color v1.9.0 // indirect + github.com/favadi/protoc-go-inject-tag v1.4.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect diff --git a/go.sum b/go.sum index 28579ac..3fd6806 100644 --- a/go.sum +++ b/go.sum @@ -28,6 +28,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/favadi/protoc-go-inject-tag v1.4.0 h1:K3KXxbgRw5WT4f43LbglARGz/8jVsDOS7uMjG4oNvXY= +github.com/favadi/protoc-go-inject-tag v1.4.0/go.mod h1:AZ+PK+QDKUOLlBRG0rYiKkUX5Hw7+7GTFzlU99GFSbQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= diff --git a/handler/hello-handler.go b/handler/hello-handler.go index f3abe09..79fec4c 100644 --- a/handler/hello-handler.go +++ b/handler/hello-handler.go @@ -1,9 +1,12 @@ package handler import ( + "fmt" + "net/http" "time" "github.com/gin-gonic/gin" + "myschools.me/suguo/go-micro-demo/model" ) func HelloWorld(c *gin.Context) { @@ -11,3 +14,22 @@ func HelloWorld(c *gin.Context) { "data": "hello world" + time.Now().String(), }) } + +func HelloSay(c *gin.Context) { + req := &model.HelloRequest{} + if err := c.ShouldBindJSON(req); err != nil { + c.Status(http.StatusBadRequest) + return + } + + data := make([]*model.HelloModel, 0) + for i := 0; i < int(req.Times%10); i++ { + data = append(data, &model.HelloModel{ + Id: int32(i), + Name: fmt.Sprintf("hello %d", i), + }) + } + c.JSON(http.StatusOK, &model.HelloResponse{ + Data: data, + }) +} diff --git a/model/hello.pb.go b/model/hello.pb.go new file mode 100644 index 0000000..3569f28 --- /dev/null +++ b/model/hello.pb.go @@ -0,0 +1,277 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc v5.28.0 +// source: proto/hello.proto + +package model + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type HelloModel struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *HelloModel) Reset() { + *x = HelloModel{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_hello_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HelloModel) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HelloModel) ProtoMessage() {} + +func (x *HelloModel) ProtoReflect() protoreflect.Message { + mi := &file_proto_hello_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HelloModel.ProtoReflect.Descriptor instead. +func (*HelloModel) Descriptor() ([]byte, []int) { + return file_proto_hello_proto_rawDescGZIP(), []int{0} +} + +func (x *HelloModel) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *HelloModel) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type HelloRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Times int32 `protobuf:"varint,1,opt,name=times,proto3" json:"times,omitempty"` +} + +func (x *HelloRequest) Reset() { + *x = HelloRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_hello_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HelloRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HelloRequest) ProtoMessage() {} + +func (x *HelloRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_hello_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HelloRequest.ProtoReflect.Descriptor instead. +func (*HelloRequest) Descriptor() ([]byte, []int) { + return file_proto_hello_proto_rawDescGZIP(), []int{1} +} + +func (x *HelloRequest) GetTimes() int32 { + if x != nil { + return x.Times + } + return 0 +} + +type HelloResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data []*HelloModel `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"` +} + +func (x *HelloResponse) Reset() { + *x = HelloResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_hello_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HelloResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HelloResponse) ProtoMessage() {} + +func (x *HelloResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_hello_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HelloResponse.ProtoReflect.Descriptor instead. +func (*HelloResponse) Descriptor() ([]byte, []int) { + return file_proto_hello_proto_rawDescGZIP(), []int{2} +} + +func (x *HelloResponse) GetData() []*HelloModel { + if x != nil { + return x.Data + } + return nil +} + +var File_proto_hello_proto protoreflect.FileDescriptor + +var file_proto_hello_proto_rawDesc = []byte{ + 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x22, 0x30, 0x0a, 0x0a, 0x48, 0x65, + 0x6c, 0x6c, 0x6f, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x24, 0x0a, 0x0c, + 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x22, 0x36, 0x0a, 0x0d, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x4d, + 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_proto_hello_proto_rawDescOnce sync.Once + file_proto_hello_proto_rawDescData = file_proto_hello_proto_rawDesc +) + +func file_proto_hello_proto_rawDescGZIP() []byte { + file_proto_hello_proto_rawDescOnce.Do(func() { + file_proto_hello_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_hello_proto_rawDescData) + }) + return file_proto_hello_proto_rawDescData +} + +var file_proto_hello_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_proto_hello_proto_goTypes = []any{ + (*HelloModel)(nil), // 0: model.HelloModel + (*HelloRequest)(nil), // 1: model.HelloRequest + (*HelloResponse)(nil), // 2: model.HelloResponse +} +var file_proto_hello_proto_depIdxs = []int32{ + 0, // 0: model.HelloResponse.data:type_name -> model.HelloModel + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_proto_hello_proto_init() } +func file_proto_hello_proto_init() { + if File_proto_hello_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_hello_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*HelloModel); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_hello_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*HelloRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_hello_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*HelloResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_hello_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_proto_hello_proto_goTypes, + DependencyIndexes: file_proto_hello_proto_depIdxs, + MessageInfos: file_proto_hello_proto_msgTypes, + }.Build() + File_proto_hello_proto = out.File + file_proto_hello_proto_rawDesc = nil + file_proto_hello_proto_goTypes = nil + file_proto_hello_proto_depIdxs = nil +} diff --git a/model/hello.pb.micro.go b/model/hello.pb.micro.go new file mode 100644 index 0000000..15ddbf1 --- /dev/null +++ b/model/hello.pb.micro.go @@ -0,0 +1,15 @@ +// Code generated by protoc-gen-micro. DO NOT EDIT. +// source: proto/hello.proto + +package model + +import ( + fmt "fmt" + proto "google.golang.org/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf diff --git a/model/proto/hello.proto b/model/proto/hello.proto new file mode 100644 index 0000000..3588748 --- /dev/null +++ b/model/proto/hello.proto @@ -0,0 +1,18 @@ +syntax="proto3"; + +package model; + +option go_package=".;model"; + +message HelloModel{ + int32 id=1; + string name=2; +} + +message HelloRequest{ + int32 times=1; +} + +message HelloResponse { + repeated HelloModel data=1; +} \ No newline at end of file diff --git a/readme.md b/readme.md index 924b26b..3a90153 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,13 @@ # go-micro DEMO #### 启动参数 - server_address :8080 \ No newline at end of file + server_address :8080 + +#### QA + +1. proto生成需要安装哪些工具件 +protobuf: https://github.com/protocolbuffers/protobuf 二进制包安装 +protoc-gen-go: go install google.golang.org/protobuf/cmd/protoc-gen-go@latest +protoc-gen-go-grpc: go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest +protoc-gen-micro: go install github.com/go-micro/generator/cmd/protoc-gen-micro@latest +protoc-go-inject-tag: go get -u github.com/favadi/protoc-go-inject-tag \ No newline at end of file diff --git a/webClient.go b/webClient.go1 similarity index 100% rename from webClient.go rename to webClient.go1 diff --git a/webClient2.go b/webClient2.go new file mode 100644 index 0000000..2832d7b --- /dev/null +++ b/webClient2.go @@ -0,0 +1,46 @@ +package main + +import ( + "context" + "fmt" + "log" + + "github.com/micro/plugins/v5/client/http" + "github.com/micro/plugins/v5/registry/consul" + "go-micro.dev/v5/client" + "go-micro.dev/v5/registry" + "go-micro.dev/v5/selector" + "myschools.me/suguo/go-micro-demo/model" +) + +func callAPI2(s selector.Selector) { + my := http.NewClient( + client.Selector(s), + client.ContentType("application/json"), + ) + + req := my.NewRequest("hello", `/v1/say`, &model.HelloRequest{ + Times: 5, + }) + var resp model.HelloResponse + if err := my.Call(context.Background(), req, &resp); err != nil { + log.Fatal(err) + } + for _, r := range resp.Data { + fmt.Printf("id=%d,name=%s\r\n", r.GetId(), r.GetName()) + } +} + +func main() { + consulReg := consul.NewRegistry( + registry.Addrs("127.0.0.1:8500"), + ) + + mySelector := selector.NewSelector( + selector.Registry(consulReg), + selector.SetStrategy(selector.RoundRobin), + ) + + callAPI2(mySelector) + +} diff --git a/webService.go b/webService.go1 similarity index 100% rename from webService.go rename to webService.go1 diff --git a/webService2.go b/webService2.go new file mode 100644 index 0000000..afa7ebe --- /dev/null +++ b/webService2.go @@ -0,0 +1,36 @@ +package main + +import ( + "time" + + "github.com/gin-gonic/gin" + "github.com/micro/go-micro/v5/web" + "github.com/micro/plugins/v5/registry/consul" + "go-micro.dev/v5/registry" + "myschools.me/suguo/go-micro-demo/handler" +) + +func main() { + consulReg := consul.NewRegistry( + registry.Addrs("127.0.0.1:8500"), + ) + ginRouter := gin.Default() + v1 := ginRouter.Group(`/v1`) + { + v1.POST(`/hello`, handler.HelloWorld) + v1.POST(`/say`, handler.HelloSay) + } + + service := web.NewService( + web.Name("hello"), + web.Handler(ginRouter), + // web.RegisterTTL(time.Second*5), + web.RegisterInterval(time.Second), + web.Address(":8080"), + web.Metadata(map[string]string{"protocol": "http"}), + web.Registry(consulReg), + ) + + service.Init() + service.Run() +}