golang 工程组件 grpc-gateway—yaml定义http规则,和自定义实现网关路由

yaml定义http规则,和自定义实现网关路由

proto定义http规则总归是麻烦的,因为proto文件还是定义消息,grpc接口好一些。配置http规则有更好的方式。我们可以使用yaml文件定义接口的http规则。 同时有些接口不是只是让网关转发这么简单 有时需要自己定网关接口handler

yaml定义http规则
type: google.api.Service
config_version: 3http:rules:# {package}.{message}.{method}- selector: user.User.Getget: "/user/{id}"- selector: user.User.AddOrUpdatepost: "/user"body: "*"additional_bindings:- put: "/user"body: "*"- patch: "/user"body: "addr"- selector: user.User.Deletedelete: "/user/{id}"

proto文件

syntax = "proto3";
package  user;
option go_package = "user/proto";message Member{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;
}message UploadRequest {int64  size = 1;bytes content = 2;
}
message UploadResponse {string filePath= 1[json_name = "file_path"];
}
service User{rpc Get(Member) returns (Member) {}rpc AddOrUpdate(Member) returns (Member) { }rpc Delete(Member) returns (Member) {}rpc Upload(stream UploadRequest) returns (UploadResponse){}
}

生成消息,grpc,网关

# 生成message 
protoc --proto_path=proto --go_out=proto --go_opt=paths=source_relative proto/user.proto 
# 生成grpc service 
protoc --proto_path=proto --go-grpc_out=proto --go-grpc_opt=paths=source_relative proto/user.proto
#生成gateway
protoc --proto_path=proto  --grpc-gateway_out=proto  --grpc-gateway_opt logtostderr=true  --grpc-gateway_opt paths=source_relative  --grpc-gateway_opt grpc_api_configuration=proto/user.yaml  proto/user.proto

参考grpc-gateway入门中的启动代码就能调用对应接口啦

自定义实现网关路由

在生成gateway后,前面proto文件中我们预留了一个文件上传grpc接口。然后在yaml中我们是没有定义对应http规则。 所以需要自定义实现对应的网关路由,来应对复杂的业务情况。

gateway.go

通过mux.HandlePath添加自定义处理的路由和对应handler函数

package gatewayimport ("context""flag""google.golang.org/grpc/health/grpc_health_v1""net/http""user/user-server/gateway/middleware""github.com/grpc-ecosystem/grpc-gateway/v2/runtime""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure"gw "user/proto"
)var (grpcServerEndpoint = flag.String("grpc-server-endpoint", "localhost:50051", "gRPC server endpoint")
)func Run() error {ctx := context.Background()ctx, cancel := context.WithCancel(ctx)defer cancel()inComingOpt := runtime.WithIncomingHeaderMatcher(func(s string) (string, bool) {switch s {case "Service-Authorization":return "service-authorization", truedefault:return "", false}return "", false})//创建连接,用于健康检查conn, err := grpc.Dial(*grpcServerEndpoint, grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {return err}mux := runtime.NewServeMux(inComingOpt, runtime.WithHealthzEndpoint(grpc_health_v1.NewHealthClient(conn)))//添加自定义处理函数mux.HandlePath("POST", "/upload", uploadHandler)handler := middleware.Cors(mux)opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}err = gw.RegisterUserHandlerFromEndpoint(ctx, mux, *grpcServerEndpoint, opts)if err != nil {return err}return http.ListenAndServe(":8081", handler)
}

upload.go

写对应网关需要注册的handler

package gatewayimport ("context""fmt""github.com/golang/protobuf/jsonpb""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure""google.golang.org/grpc/metadata""io""net/http""user/proto"
)func uploadHandler(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {serviceAuthorization := r.Header.Get("Service-Authorization")fmt.Println(serviceAuthorization)err := r.ParseForm()if err != nil {http.Error(w, fmt.Sprintf("上传失败:%s", err.Error()), http.StatusInternalServerError)return}f, header, err := r.FormFile("attachment")if err != nil {http.Error(w, fmt.Sprintf("上传失败:%s", err.Error()), http.StatusInternalServerError)return}defer f.Close()conn, err := grpc.Dial(*grpcServerEndpoint, grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {http.Error(w, fmt.Sprintf("上传失败:%s", err.Error()), http.StatusInternalServerError)return}defer conn.Close()c := proto.NewUserClient(conn)ctx := context.Background()ctx = metadata.NewOutgoingContext(ctx, metadata.New(map[string]string{"file_name": header.Filename, "service-authorization": serviceAuthorization}))stream, err := c.Upload(ctx)if err != nil {http.Error(w, fmt.Sprintf("上传失败:%s", err.Error()), http.StatusInternalServerError)return}buf := make([]byte, 100)for {n, err := f.Read(buf)if err != nil && err != io.EOF {http.Error(w, fmt.Sprintf("上传失败:%s", err.Error()), http.StatusInternalServerError)return}if n == 0 {break}stream.Send(&proto.UploadRequest{Content: buf[:n],Size:    int64(n),})}res, err := stream.CloseAndRecv()if err != nil {http.Error(w, fmt.Sprintf("上传失败:%s", err.Error()), http.StatusInternalServerError)return}m := jsonpb.Marshaler{}str, err := m.MarshalToString(res)if err != nil {http.Error(w, fmt.Sprintf("上传失败:%s", err.Error()), http.StatusInternalServerError)return}w.Header().Add("Content-Type", "application/json")fmt.Fprint(w, str)
}

重新启动即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/121875.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM相关面试题(每日一练)

1. 什么是垃圾回收机制? 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了。 jvm 中,程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭&a…

在本地模拟C/S,Socket套接字的使用

public class SocketTCP01Server {public static void main(String[] args) throws IOException {/**1.在本机的 9999 端口监听 ,等待连接细节: 要求在本机没有其他服务在监听999细节:这个ServerSocket 可以通过accept()返回多个Socket[多个客…

网关概念及java项目中用使用网关场景

网关(Gateway)是一个在网络系统中起到入口和出口的作用的组件或服务。它位于客户端和服务器之间,负责处理进出网络的流量,实现一些重要的功能,如路由、安全认证、协议转换等。 网关在网络架构中扮演了多种角色&#x…

使用Jenkins触发gitlab的webhook

满足条件: 首先手动构建可以完成构建 例如: 打开项目点击配置 在“Build Triggers”栏勾选,Build when a change is pushed to GitLab. GitLab webhook ;如下 复制URL链接,我的链接是:http://192.168.44…

TypeScript - 字符串的字面类型

啥是字面量类型 字面量类型,是限制了一个字符串变量的取值范围只能某几个固定字符串中的一个。 我感觉 与枚举类型有异曲同工之妙。 字符串字面量类型有啥用 没啥用。 就是来限制字符串变量不能随便赋值的。 定义一个我看看 让你读书,但是只有四本书可以…

设计模式之门面模式

前言 什么是门面模式 门面模式是一种结构型设计模式,它提供了一个统一的接口,用来访问子系统中的一群接口。它定义了一个高层接口,让子系统更容易使用。这种模式常用于将一个复杂的子系统封装成一个简单的接口,使得客户端可以方…

Java 枚举类型与泛型-第13章

Java 枚举类型与泛型-第13章 1.枚举类型 枚举类型是一种特殊的数据类型,用于表示一组有限的命名常量。枚举类型可以帮助您更清晰地定义和管理相关常量,并提供类型安全性。 1.1使用枚举类型设置常量 枚举类型是一种非常方便的方式来设置常量。我们可以…

JavaScript简介

JavaScript是一种高级的、解释型的编程语言,用于在网页上实现交互和动态效果。它广泛应用于前端开发中,是构建现代Web应用的核心技术之一。JavaScript可以直接嵌入到HTML页面中,并通过浏览器解释执行。 历史与发展 JavaScript由Netscape公司…

基于51单片机的温度测量报警系统的设计与制作

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、实习目的二、实习任务2.1 设计温度测量报警系统硬件电路2.2 温度测量报警系统软件编程、仿真与调试;2.3 完成温度测量报警系统的实物制作与调试…

从一线到联合,克唑替尼在ALK阳性NSCLC治疗新旅程【医游记】

(图片来源于网络) 一、克唑替尼简介 克唑替尼(Crizotinib),商品名赛可瑞,是一款口服服用的小分子酪氨酸激酶抑制剂。克唑替尼最早于2011年被美国FDA批准用于ALK阳性晚期NSCLC的治疗。其主要靶点为间变淋巴瘤激酶(ALK)和ROS1(ROS proto-oncogene 1)融合…

记录:获取windows当前登录的用户信息

参考: 获取列表:用户信息 作为系统帐户运行的Windows服务如何获得当前用户的\AppData\Local\专用文件夹?-腾讯云开发者社区-腾讯云 (tencent.com) 获取当前账号:域\用户名 c#如何从 .NET 中的 Windows 服务获取当前记录的用户…

3.1、Linux的vim编辑器

个人主页:Lei宝啊 愿所有美好如期而遇 目录 前言: 插入模式 底行模式 命令模式 前言: 没有进行配置的vim编辑器在写代码时和记事本没什么两样,所以最开始我们可以先下载一个插件,在Linux下两行指令的问题&…

视频格式高效转换:MP4视频批量转MKV格式的方法

随着数字媒体技术的不断发展,视频格式转换已经成为了我们日常工作中不可或缺的一部分。不同的视频格式适用于不同的场景和设备,因此将视频从一种格式转换为另一种格式往往是我们必须完成的任务。在本文中,我们将重点介绍如何运用云炫AI智剪高…

Apollo安装全攻略

安装方式 概述快速安装安装基础软件安装 Ubuntu Linux安装 Docker Engine 安装 Apollo 环境管理工具获取 GPU 支持(可选)创建和进入 Apollo 环境容器 源码安装安装 Linux 系统(可选)安装 NVIDIA GPU 驱动安装 docker下载并编译 Ap…

go中网络流量分析gopacket库的使用

一、前言 近来,笔者想学习下用go构造tcp数据包,这里涉及到gopacket库的使用,故这里记录下关于gopacket库的一些学习记录 二、介绍 gopacket 是 Go 语言的网络数据包处理库,它提供了方便的 API 来读取、分析、修改和生成网络数据包…

【Linux】安装配置解决CentosMobaXterm的使用及Linux常用命令命令模式

目录 一、介绍 1. 背景 2. 讲述&功能 二、Centos安装配置&MobaXterm 1. 创建 2. 安装 3. 配置 4. MobaXterm使用 三、Linux常用命令&模式 1. 常用命令 2. 三种模式 3. 命令使用&换源 4. 拍照备份 一、介绍 1. 背景 CentOS的背景可以追溯到200…

STM32F4X SDIO(二) SDIO协议

上一节简单介绍了SD卡的分类,本节将会介绍SD卡的通信协议,也就是SDIO协议。 STM32F4X SDIO(二)SDIO协议 SD 卡管脚和寄存器SD卡管脚分布SD卡通信协议SD卡寄存器SD卡内部结构 SDIO总线SDIO总线拓扑SDIO总线协议SDIO协议的基本结构…

java将list转为逗号隔开字符串,将逗号连接的字符串转成字符数组,​将逗号分隔的字符串转换为List​(Java逗号分隔-字符串与数组相互转换)

一、通过testList.stream().collect(Collectors.joining(",")) &#xff0c;通过流转换&#xff0c;将list转为逗号隔开字符串 List<String> testList new ArrayList<>(); testList.add("test1"); testList.add("test2"); testList…

Python的比较运算符查询表

据个人的编程开发经验&#xff0c;Python的比较运算符最常于条件判断&#xff0c;而条件判断是python编程中最常用的语法之一&#xff0c;与for或while的循环一样&#xff0c;功能十分强大&#xff01; 在机器学习当中&#xff0c;或深度学习当中&#xff0c;在运用算法对统计…

ArcGIS笔记12_ArcGIS搜索工具没法用?ArcGIS运行很慢很卡?

本文目录 前言Step 1 ArcGIS搜索工具没法用Step 2 ArcGIS运行很慢很卡 前言 这是笔者最近遇到的两个小问题&#xff0c;新换了台式机&#xff0c;安装上ArcGIS后发现搜索工具没法用&#xff0c;而且感觉还不如原来笔记本运行的流畅&#xff0c;加载图层很慢&#xff0c;编辑要…