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
}

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

相关推荐
意倾城5 分钟前
Spring Boot 配置文件敏感信息加密:Jasypt 实战
java·spring boot·后端
火皇4055 分钟前
Spring Boot 使用 OSHI 实现系统运行状态监控接口
java·spring boot·后端
mahuifa17 分钟前
python实现usb热插拔检测(linux)
linux·服务器·python
薯条不要番茄酱37 分钟前
【SpringBoot】从零开始全面解析Spring MVC (一)
java·spring boot·后端
朱四龙44 分钟前
http接口性能优化方案
网络协议·http·性能优化
Clown951 小时前
Go语言爬虫系列教程(一) 爬虫基础入门
开发语言·爬虫·golang
Hello.Reader3 小时前
ngx_http_limit_conn_module精准连接控制
网络·网络协议·http
π大星星️4 小时前
基于LNMP架构的个人博客系统部署
服务器·架构
巴巴_羊7 小时前
前端面经 计网 http和https区别
网络协议·http·https
懵逼的小黑子8 小时前
Django 项目的 models 目录中,__init__.py 文件的作用
后端·python·django