grpc-gateway-example

command module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 8, 2023 License: MIT Imports: 8 Imported by: 0

README

grpc-gateway-example

grpc-gateway的使用示例,其中集成了各类库。

集成

  • grpc-gateway
  • viper
  • zap
  • otel
  • gorm
  • redigo

使用

1.用protocol buffer 定义grpc服务并生成go文件

参考proto/src/api/v1/example/example.proto

syntax = "proto3";

package flamefatex.grpc_gateway_example.api.v1.example;

import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/empty.proto";
import "validate/validate.proto";

import  "common/paging/paging.proto";
import  "common/status/status.proto";
import  "enumeration/example.proto";

// ExampleService 示例服务
service ExampleService {
  // List 查询示例列表
  rpc List(ExampleListRequest) returns (ExampleListResponse) {
    option (google.api.http) = {
      get: "/api/v1/example/list"
    };
  }
  
}

// Example 示例
message Example {
  // ID
  string id = 1;
  // 名称
  string name = 2;
  // 类型
  flamefatex.grpc_gateway_example.enumeration.ExampleType type = 3;
  // 描述
  string description = 4;
  // 创建时间
  google.protobuf.Timestamp created_at = 5;
  // 更新时间
  google.protobuf.Timestamp updated_at = 6;
}

// ExampleListRequest 查询示例列表请求
message ExampleListRequest {
  // 分页
  flamefatex.grpc_gateway_example.common.paging.Paging paging = 1;
  // ID
  string id = 2;
  // 名称
  string name = 3;
}

// ExampleListResponse 查询示例列表响应
message ExampleListResponse {
  // 请求ID
  string request_id = 1;
  // 请求状态
  flamefatex.grpc_gateway_example.common.status.Status status = 2;
  // 分页
  flamefatex.grpc_gateway_example.common.paging.Paging paging = 3;
  // 示例列表
  repeated Example examples = 4;
}

执行makefile指令

make buf-gen

2.定义模型与生成query DAO

参考model/example.go

package model

import (
	"time"

	proto_enum "github.com/flamefatex/grpc-gateway-example/proto/gen/go/enumeration"
	"gorm.io/gen"
)

type Example struct {
	Id          string
	Name        string
	Type        proto_enum.ExampleType
	Description string
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

// ExampleQueryInterface example自定义查询接口
type ExampleQueryInterface interface {
	// SELECT * FROM @@table
	// WHERE
	// {{ if id != "" }} id = @id AND {{ end }}
	// {{ if name != "" }} name LIKE %@name% AND {{ end }}
	// 1=1
	Query(id string, name string) ([]*gen.T, error)
}

func (m *Example) TableName() string {
	return "example"
}


执行makefile指令

make gorm-gen

3. 实现你的grpc服务

参考handler/api/v1/example.go

package v1

import (
	"context"
	"fmt"
	"strings"
	"time"

	"github.com/flamefatex/grpc-gateway-example/model"
	"github.com/flamefatex/grpc-gateway-example/model/query"
	"github.com/flamefatex/grpc-gateway-example/pkg/lib/errorx"
	util_paging "github.com/flamefatex/grpc-gateway-example/pkg/util/paging"
	proto_v1_example "github.com/flamefatex/grpc-gateway-example/proto/gen/go/api/v1/example"
	proto_enum "github.com/flamefatex/grpc-gateway-example/proto/gen/go/enumeration"
	"github.com/rs/xid"
	"google.golang.org/grpc/codes"
	"google.golang.org/protobuf/types/known/timestamppb"
	"gorm.io/gen"
)

type exampleHandler struct {
	proto_v1_example.UnimplementedExampleServiceServer
}

func NewExampleHandler() *exampleHandler {
	return &exampleHandler{}
}

func (h *exampleHandler) List(ctx context.Context, req *proto_v1_example.ExampleListRequest) (resp *proto_v1_example.ExampleListResponse, err error) {
	resp = &proto_v1_example.ExampleListResponse{}
	req.Paging = pagingx.Normalize(req.Paging)

	q := query.Example
	// 组装条件
	conditions := make([]gen.Condition, 0)
	if req.Id != "" {
		conditions = append(conditions, q.Id.Eq(req.Id))
	}
	if req.Name != "" {
		conditions = append(conditions, q.Name.Like("%"+req.Name+"%"))
	}

	examples, total, err := q.WithContext(ctx).
		Where(conditions...).
		Order(q.Id.Desc()).
		FindByPage(pagingx.OffsetLimit(req.Paging))
	if err != nil {
		err = errorx.ErrorfInternalServer("EXAMPLE_LIST_ERROR", "get example list failed, err: %s", err)
		return
	}

	rsExamples := make([]*proto_v1_example.Example, 0)
	for _, example := range examples {
		e := &proto_v1_example.Example{
			Id:          example.Id,
			Name:        example.Name,
			Type:        example.Type,
			Description: example.Description,
			CreatedAt:   timestamppb.New(example.CreatedAt),
			UpdatedAt:   timestamppb.New(example.UpdatedAt),
		}
		rsExamples = append(rsExamples, e)
	}

	resp.Examples = rsExamples
	resp.Paging = pagingx.WithTotal(req.Paging, total)
	return
}

4. 注册grpc server和http endpoint

参考handler/register_grpc.go注册grpc server

package handler

import (
	"context"

	v1 "github.com/flamefatex/grpc-gateway-example/handler/api/v1"
	proto_v1_example "github.com/flamefatex/grpc-gateway-example/proto/gen/go/api/v1/example"
	"google.golang.org/grpc"
)

// ExecRegisterGrpcServiceServer 注册grpc服务处理器
func ExecRegisterGrpcServiceServer(ctx context.Context, grpcServer *grpc.Server) {
	// 注册
	proto_v1_example.RegisterExampleServiceServer(grpcServer, v1.NewExampleHandler())
}

参考handler/register_grpc_gateway.go注册http endpoint

package handler

import (
	"context"

	proto_v1_example "github.com/flamefatex/grpc-gateway-example/proto/gen/go/api/v1/example"
	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
	"google.golang.org/grpc"
)

type GrpcGwRegister func(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error)

// ExecRegisterGrpcGatewayEndpoint 注册grpc gateway 端点
func ExecRegisterGrpcGatewayEndpoint(ctx context.Context) []GrpcGwRegister {
	regs := []GrpcGwRegister{
		// 注册http端点
		proto_v1_example.RegisterExampleServiceHandlerFromEndpoint,
	}
	return regs
}

5. 编译与访问

go run main.go

然后访问 localhost:8082/api/v1/example/list

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL