快速实现golang的grpc服务
·
1、安装服务
1、protoc安装
需去官网下载
protobuf
2、命令行安装protoc-gen-go和protoc-gen-go-grpc
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
2、检查安装版本情况
protoc --version
# libprotoc 29.0
protoc-gen-go --version
# protoc-gen-go v1.28.1
protoc-gen-go-grpc --version
# protoc-gen-go-grpc 1.2.0
3、编写proto文件
syntax = "proto3";
import "google/protobuf/descriptor.proto";
import "information.proto";
import "interfaceTest.proto";
package interfaceTest;
option go_package="gopkg.inshopline.com/demo/book/api/grpc/gen/testGateway";
message NodeReq{
string id = 1;
repeated string ids = 2;
interfaceTest.baseDto baseField = 3;
information.OpenAPIContext openAPIContext = 4;
}
message TestDataTypeNodeListResponse{
string code = 1;
string message = 2;
repeated interfaceTest.InterfaceDataTypeReq data = 3;
}
service TestGatewayService {
rpc testDataTypeNode(NodeReq) returns(TestDataTypeNodeListResponse);
}
4、生成代码
#!/bin/bash
# 与proto放在同一级,当前目录生成**.grpc.pb.go和**.pb.go
protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative interfaceTest.proto
或者
#!/bin/bash
# gRPC二方API库相对于当前脚本的文件路径
working_directory=./grpc
cd $working_directory || exit 1
echo working_directory="$(pwd)"
if [ ! -f "go.mod" ]; then
echo no go.mod file in "$(pwd)"
exit 1
fi
module=$(grep '^module' go.mod | head -1)
module_path=${module#*"module "}
echo module_path="$module_path"
cd ./proto || exit 1
# package specification: https://protobuf.dev/reference/go/go-generated/#package
for f in *.proto; do
if [ ! -f "$f" ]; then
continue
fi
cmd="protoc \\
--proto_path=. \\
--go_out=../gen/ \\
--go_opt=module=$module_path/gen \\
--go-grpc_out=require_unimplemented_servers=false:../gen/ \\
--go-grpc_opt=module=$module_path/gen \\
$f"
echo command="$cmd"
eval "$cmd"
done
然后会生成2个文件
testGateway.pb.go
testGateway_grpc.pb.go
5、实现业务逻辑
实现proto中定义的方法
testGateway_grpc.pb.go中代码片段
// TestGatewayServiceServer is the server API for TestGatewayService service.
// All implementations should embed UnimplementedTestGatewayServiceServer
// for forward compatibility
type TestGatewayServiceServer interface {
TestDataTypeNode(context.Context, *NodeReq) (*TestDataTypeNodeListResponse, error)
}
// UnimplementedTestGatewayServiceServer should be embedded to have forward compatible implementations.
type UnimplementedTestGatewayServiceServer struct {
}
实现TestGatewayServiceServer方法
package testGateway
import (
"context"
"encoding/json"
"errors"
"fmt"
"gopkg.inshopline.com/commons/logx"
"gopkg.inshopline.com/demo/book/api/grpc/gen/interfaceTest"
"gopkg.inshopline.com/demo/book/api/grpc/gen/testGateway"
"time"
)
var (
logger = logx.GetLogger("core-testGateway")
_ testGateway.TestGatewayServiceServer = (*TestGatewayService)(nil)
)
type TestGatewayService struct {
testGateway.UnimplementedTestGatewayServiceServer
}
func (t TestGatewayService) TestDataTypeNode(ctx context.Context, req *testGateway.NodeReq) (*testGateway.TestDataTypeNodeListResponse, error) {
reqBody, _ := json.Marshal(req)
logger.Infof(ctx, "TestDataTypeNode request body: %s", string(reqBody))
result := &testGateway.TestDataTypeNodeListResponse{
Code: "0",
Message: "success",
Data: []*interfaceTest.InterfaceDataTypeReq{},
}
resonse := &interfaceTest.InterfaceDataTypeReq{}
mockRes := ""
for _, reqId := range req.Ids {
switch reqId {
case "1":
mockRes = "{\"id\":\"1\",\"dataURL\":\"1\",\"dataURI\":\"1\",\"dataUUID\":\"1\",\"dataFloat\":323.12,\"dataDouble\":434.23,\"dataString\":\"test interface\",\"dataBigDecimal\":132.23,\"dataBoolean\":true,\"dataShort\":12,\"dataChar\":\"c\",\"dataInt\":123,\"dataListStr\":[\"13\",\"设计gql\"],\"dataObject\":{\"objectId\":\"144fas\",\"objectSex\":\"男\",\"objectName\":\"黑海\"},\"dataObjectList\":[{\"objectId\":\"144fas\",\"objectSex\":\"男\",\"objectName\":\"黑海\"},{\"objectId\":\"jdisf1443\",\"objectSex\":\"女\",\"objectName\":\"闰土\"}],\"dataMap\":{\"mapKey\":\"name\",\"mapValue\":\"哈哈\"},\"dataMapList\":[{\"mapKey\":\"name\",\"mapValue\":\"哈哈\"},{\"mapKey\":\"hua\",\"mapValue\":\"heiei\"}]}"
err := json.Unmarshal([]byte(mockRes), &resonse)
if err != nil {
logger.Errorf(ctx, "json unmarshal err: %s", err.Error())
result.Code = "1"
result.Message = fmt.Sprintf("json unmarshal err: %s", err.Error())
break
}
case "2":
mockRes = "{\"id\":\"2\",\"dataURL\":\"2\",\"dataURI\":\"2\",\"dataUUID\":\"2\",\"dataFloat\":0.0,\"dataDouble\":0.0,\"dataString\":\"2\",\"dataBigDecimal\":22.22,\"dataBoolean\":false,\"dataShort\":0,\"dataChar\":\"\\u0000\",\"dataInt\":0,\"dataListStr\":[\"22\",\"设计gql22\"],\"dataObject\":null,\"dataObjectList\":null,\"dataMap\":null,\"dataMapList\":[{\"mapKey\":null,\"mapValue\":null},{\"mapKey\":\"hua\",\"mapValue\":\"heiei\"}]}"
err := json.Unmarshal([]byte(mockRes), &resonse)
if err != nil {
logger.Errorf(ctx, "json unmarshal err: %s", err.Error())
result.Code = "1"
result.Message = fmt.Sprintf("json unmarshal err: %s", err.Error())
break
}
case "3":
break
case "4":
return &testGateway.TestDataTypeNodeListResponse{
Code: "0",
Message: "test data is []",
}, nil
case "5":
time.Sleep(3 * time.Second)
break
case "6":
return nil, errors.New("异常测试")
case "7":
result.Code = "TS001"
result.Message = "错误码测试"
case "8":
result.Code = "TS002"
result.Message = "错误码测试2"
}
result.Data = append(result.Data, resonse)
}
return result, nil
}
6、创建provider
package provider
import (
"context"
test_gateway "demo/book/core/biz/testGateway"
"gopkg.inshopline.com/demo/book/api/grpc/gen/testGateway"
)
// @Author: lyd
// @File: testGatewayService.go
// @Date: 2025/6/12 11:19
// @Description: 测试网关
type TestGatewayProvider struct {
}
var (
_ testGateway.TestGatewayServiceServer = (*TestGatewayProvider)(nil)
testGatewayService = &test_gateway.TestGatewayService{}
)
func (T *TestGatewayProvider) TestDataTypeNode(ctx context.Context, req *testGateway.NodeReq) (*testGateway.TestDataTypeNodeListResponse, error) {
return testGatewayService.TestDataTypeNode(ctx, req)
}
package provider
import (
"google.golang.org/grpc"
"gopkg.inshopline.com/demo/book/api/grpc/gen/testGateway"
)
func RegisterGrpcProvider(server *grpc.Server) {
testGateway.RegisterTestGatewayServiceServer(server, &TestGatewayProvider{})
}
然后启动时注册上去就好了
7、测试调用
postman调用正常
更多推荐




所有评论(0)