golang 工程组件:grpc-gateway option自定义http规则

option自定义http规则和http body响应

简介

本篇接上文

golang 工程组件:grpc-gateway 环境安装+默认网关测试

默认网关配置终究是难用,本篇介绍一下proto里采用option自定义http规则以及让网关返回http响应而不是我们定义的grpc响应

option定义http规则和httpbody响应

引入库。可以直接拷贝grpc-gateway源码下google文件夹到项目下

复制代码
import "google/api/annotations.proto";
import "google/api/httpbody.proto";
import "google/protobuf/empty.proto";

user.proto

protobuf 复制代码
syntax = "proto3";
package  echo;
option go_package = "echo/proto";

import "google/api/annotations.proto";
import "google/api/httpbody.proto";
import "google/protobuf/empty.proto";


message User{
  int64 id = 1;
  // 改成下划线形式
  string userName = 2[json_name="user_name"];
  int32 age = 3;
  string phone = 4;
  Addr addr = 5;
}

message Addr {
  string province = 1;
  string city = 2;
  string county = 3;
}

service Echo{
  rpc Get(User) returns (User) {
  	//get请求
    option (google.api.http) = {
      get: "/echo/user/{id}"
    };
  }
  rpc AddOrUpdate(User) returns (User) {
    option (google.api.http) = {
      post: "/echo/user"
      // * 表示接受user所有字段
      body: "*"
      additional_bindings {
        put: "/echo/user"
        body: "*"
      }
      //patch 请求,只更新部分字段
      additional_bindings {
        patch: "/echo/user"
        body: "addr"
      }
    };
  }
  rpc Delete(User) returns (User) {
    option (google.api.http) = {
        delete: "/echo/user/{id}"
     };
  }
  // httpbody响应,前面是grpc定义的消息
  rpc List(google.protobuf.Empty) returns (stream google.api.HttpBody) {
    option (google.api.http) = {
       get: "/echo/user/list"
    };
  }
}

对应grpc实现

server.go

go 复制代码
package server

import (
    "context"
    "echo/proto"
    "fmt"
    "github.com/golang/protobuf/jsonpb"
    _ "github.com/golang/protobuf/jsonpb"
    "google.golang.org/genproto/googleapis/api/httpbody"
    _ "google.golang.org/genproto/googleapis/api/httpbody"
    "google.golang.org/protobuf/types/known/emptypb"
    _ "google.golang.org/protobuf/types/known/emptypb"
)

type echoServer struct {
    proto.UnimplementedEchoServer
}

func NewServer() proto.EchoServer {
    return &echoServer{}
}
func (s *echoServer) Get(ctx context.Context, in *proto.User) (*proto.User, error) {
    fmt.Printf("%+v\n", in)
    return in, nil
}
func (s *echoServer) AddOrUpdate(ctx context.Context, in *proto.User) (*proto.User, error) {
    fmt.Printf("%+v\n", in)
    return in, nil
}
func (s *echoServer) Delete(ctx context.Context, in *proto.User) (*proto.User, error) {
    fmt.Printf("%+v\n", in)
    return in, nil
}

func (s *echoServer) List(in *emptypb.Empty, stream proto.Echo_ListServer) error {
    userList := []*proto.User{
        {
            Id:       1,
            UserName: "test1",
            Addr: &proto.Addr{
                Province: "深圳1",
            },
        },
        {
            Id:       2,
            UserName: "test2",
            Addr: &proto.Addr{
                Province: "深圳2",
            },
        },
        {
            Id:       3,
            UserName: "test3",
            Addr: &proto.Addr{
                Province: "深圳3",
            },
        },
    }
    for _, u := range userList {
        //jsonpb库序列化返回的才是下划线形式。 json序列化不读tag里定义
        m := jsonpb.Marshaler{}
        data, _ := m.MarshalToString(u)
        msg := &httpbody.HttpBody{
            ContentType: "application/json",
            Data:        []byte(data),
        }
        stream.Send(msg)
    }
    return nil
}

启动后按对应路由访问即可。 网关和启动源码在上文里

相关推荐
码剑客4 分钟前
Gin+GORM+Redis 项目开发常见性能坑汇总(Go后端避坑指南)
redis·后端·golang·gin
AI日报派送佬6 分钟前
2026年11月02日 AI 行业日报|商汤开源 Loop-9B、Pika 发布 H3 Flex 音视频模型、Meta× 傅利叶推出人形机器人 Max
人工智能·微软·开源·音视频·openai·1024程序员节·ai日报
凯基迪科技26 分钟前
瑞萨R5F100解密 R8C/RL78 MCU 固件读取与保护机制详解
服务器·网络·单片机
java_nnnn29 分钟前
Spring Boot 配置文件详解:从基础语法到 YAML 配置
spring boot·后端·github
SimonKing29 分钟前
素笺( local-notes)全面优化,新增功能体验不一样的笔记
java·后端·程序员
avi911130 分钟前
【AI教人】UnityEditor扩展Spine动画,Spine骨骼,预览Preview一切
spine·骨骼动画·1024程序员节·editor扩展·spine动画·spine骨骼
FungLeo34 分钟前
成为全栈·Go 后端篇·换后端不改前端:四个客户端如何做兼容回归
flutter·golang·go·成为全栈·兼容测试·taro 小程序
何中应39 分钟前
【Go-1】变量&常量定义
开发语言·后端·golang
愚农搬码1 小时前
电子表单、动态表单、表单设计器和表单引擎到底有什么区别?
java·后端
挖掘狂人1 小时前
Redis 为什么快?把 "存内存" 这句话拆开看
redis·后端·性能优化