成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Golang 語言 gRPC 服務怎么同時支持 gRPC 和 HTTP 客戶端調(diào)用?

開發(fā) 前端
gRPC 客戶端服務的前提下,gRPC 服務端服務怎么同時支持 gRPC 和 HTTP 客戶端調(diào)用?今天我們介紹一個 protoc 插件 gRPC-Gateway。

01介紹

關(guān)于 gRPC 的文章,我們之前寫過幾篇,如果讀者朋友還對 gRPC 不了解,我建議您可以翻閱一下公眾號的歷史文章。

當我們需要提供 gRPC 服務的 RESTful API 時,可以先創(chuàng)建一個 gRPC 客戶端服務,在 gRPC 客戶端服務編寫 RESTful API,接收到 HTTP 請求時,通過 gRPC 客戶端服務調(diào)用 gRPC 服務端服務的方法。

相信讀者朋友們也意識到,僅僅為了提供 RESTful API 而編寫一個 gRPC 客戶端服務,顯然有些小題大做。

在不借助 gRPC 客戶端服務的前提下,gRPC 服務端服務怎么同時支持 gRPC 和 HTTP 客戶端調(diào)用?今天我們介紹一個 protoc 插件 gRPC-Gateway。

02gRPC-Gateway

gRPC-Gateway 是 protoc 的一個插件。它讀取 gRPC 服務定義并生成一個反向代理服務器,該服務器將 RESTful JSON API 轉(zhuǎn)換為 gRPC。此服務器是根據(jù) gRPC 定義中的自定義選項生成的。

gRPC-Gateway 可幫助您同時以 gRPC 和 RESTful 風格提供 API。

在我們開始編碼之前,需要一些先決條件。

首先,我們需要先搭建一個 Go 環(huán)境。

使用 go get 工具下載一些依賴包。

使用 go mod init 工具創(chuàng)建一個 go.mod 文件。

依賴包列表:

$ go get github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway
$ go get google.golang.org/protobuf/cmd/protoc-gen-go
$ go get google.golang.org/grpc/cmd/protoc-gen-go-grpc

03gRPC-Gateway 實戰(zhàn)

在完成以上先決條件后,我們創(chuàng)建一個 gRPC 服務端服務,本文我們創(chuàng)建一個 ToDoList gRPC 服務。在創(chuàng)建 gRPC 服務之前,我們使用 protocol buffers 創(chuàng)建一個 proto 文件。

創(chuàng)建 proto 文件

...
service ToDoList {
rpc CreateToDoList (ToDoListDetail) returns (CreateToDoListResult) {}
rpc ReadToDoList (ToDoListPage) returns (ReadToDoListByPage) {}
}
...

生成 gRPC 服務端存根

使用 protoc 命令工具生成存根

protoc -I proto \
--go_out ./pb/todoPb --go_opt paths=source_relative \
--go-grpc_out ./pb/todoPb --go-grpc_opt paths=source_relative \
proto/toDoList.proto

執(zhí)行上面 protoc 命令工具,生成一個 *.pb.go 文件和一個 *_grpc.pb.go 文件。

編寫剩余 Go 代碼

創(chuàng)建 main.go

func main() {
InitEngine()
lis, err := net.Listen("tcp", address)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
server := grpc.NewServer()
pb.RegisterToDoListServer(server, new(service.ToDoList))
log.Printf("server listening at %v\n", lis.Addr())
if err := server.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}

添加 gRPC-Gateway 選項

gRPC-Gateway 使用 google.api.http 選項定義 gRPC 服務如何映射到 JSON 請求和響應,使用 protoc 時,每個 RPC 必須使用 google.api.http 選項定義 HTTP 方法和路徑。

因此,我們需要將 google/api/http.proto 導入添加到 proto 文件中。我們還需要添加我們想要的 HTTP -> gRPC 映射。

syntax = "proto3";

import "google/api/annotations.proto";

service ToDoList {
rpc CreateToDoList (ToDoListDetail) returns (CreateToDoListResult) {
option (google.api.http) = {
post: "/v1/todolist/add"
body: "*"
};
}
rpc ReadToDoList (ToDoListPage) returns (ReadToDoListByPage) {
option (google.api.http) = {
get: "/v1/todolist/select"
};
}
}
...

關(guān)于 HTTP 和 gRPC 映射的更多內(nèi)容,可以參閱 Google API 文檔。

生成 gRPC-Gateway 存根

現(xiàn)在,我們已將 gRPC-Gateway 選項添加到 proto 文件中,我們需要使用 gRPC-Gateway 生成器來生成存根。

在使用 protoc 生成存根之前,我們需要將一些依賴項復制到 proto 文件目錄中。將 googleapis 的子集從官方存儲庫下載并復制到本地 proto 文件目錄中。如下所示:

.
├── dao
│ ├── mysql.go
│ └── toDoList.go
├── grpc-gateway
│ └── main.go
├── main.go
├── pb
│ └── todoPb
│ ├── toDoList.pb.go
│ ├── toDoList.pb.gw.go
│ └── toDoList_grpc.pb.go
├── proto
│ ├── google
│ │ └── api
│ │ ├── annotations.proto
│ │ └── http.proto
│ └── toDoList.proto
└── service
└── toDoList.go

使用 protoc 生成存根

protoc -I proto \
--go_out ./pb/todoPb --go_opt paths=source_relative \
--go-grpc_out ./pb/todoPb --go-grpc_opt paths=source_relative \
--grpc-gateway_out ./pb/todoPb --grpc-gateway_opt paths=source_relative \
proto/toDoList.proto

protoc-go-inject-tag -XXX_skip=xorm -input=./pb/todoPb/toDoList.pb.go

執(zhí)行以上 protoc 命令工具,生成一個 *.gw.pb.go 文件。

創(chuàng)建 grpc-gateway 目錄,并創(chuàng)建 main.go 文件,創(chuàng)建 gRPC-Gateway 多路復用器。

func main() {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()

mux := runtime.NewServeMux()
opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
err := pb.RegisterToDoListHandlerFromEndpoint(ctx, mux, grpcServerEndpoint, opts)
if err != nil {
log.Fatalf("Fail to register gRPC gateway service endpoint: %v", err)
}

if err = http.ListenAndServe(":8080", mux); err != nil {
log.Fatalf("Could not setup HTTP endpoint: %v", err)
}
}

啟動服務

grpc 服務

go run main.go

gRPC-Gateway

go run grpc-gateway/main.go

cURL 測試

curl http://127.0.0.1:8080/v1/todolist/select?page=1&count=2

響應結(jié)果:

{
"todolist": [
{
"id": "1",
"content": "編程寫代碼",
"datetime": "1632541505",
"created": "1632541505",
"updated": "1632541505"
},
{
"id": "2",
"content": "編程寫代碼",
"datetime": "1632543373",
"created": "1632543373",
"updated": "1632543373"
}
]
}

04總結(jié)

本文我們介紹 gRPC-Gateway 如何實現(xiàn)同時支持 gRPC 和 RESTful 風格的 API。

當 HTTP 請求到達 gRPC-Gateway 時,它會將 JSON 數(shù)據(jù)解析為 protobuf 消息。然后,它使用解析的 protobuf 消息發(fā)出正常的 Go gRPC 客戶端請求。

Go gRPC 客戶端將 protobuf 結(jié)構(gòu)編碼為 protobuf 二進制格式,并將其發(fā)送到 gRPC 服務器。gRPC 服務器處理請求并以 protobuf 二進制格式返回響應。

Go gRPC 客戶端將其解析為 protobuf 消息,并將其返回到 gRPC-Gateway,后者將 protobuf 消息編碼為 JSON 并將其返回到原始客戶端。

圖片來自 gRPC-Gateway 官方文檔


責任編輯:武曉燕 來源: Golang語言開發(fā)棧
相關(guān)推薦

2022-04-29 11:52:02

API代碼HTTP

2021-09-13 05:02:49

GogRPC語言

2021-10-18 05:00:38

語言GoRequestHTTP

2021-09-26 10:20:06

開發(fā)Golang代碼

2021-07-28 11:46:51

工具gRPC客戶端

2021-09-01 23:29:37

Golang語言gRPC

2021-05-07 15:28:03

Kafka客戶端Sarama

2022-01-05 08:03:23

C#通信Rest

2025-01-13 06:00:00

Go語言gRPC

2021-11-29 07:47:57

gRPCGUI客戶端

2023-03-28 07:03:15

gRPCMetadata

2025-02-04 13:53:18

NixGogRPC

2023-03-02 07:20:10

GRPC服務健康檢查協(xié)議

2024-04-22 09:30:24

2024-02-05 08:50:57

Golang標準庫客戶端

2025-05-20 09:39:57

GogRPC微服務

2023-09-06 07:17:57

2023-06-10 23:01:41

GrpcProtobuf數(shù)據(jù)

2009-12-21 10:19:05

Silverlight

2023-03-05 23:11:07

Go語言服務
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 中文字幕一区二区三区在线观看 | 国产精品福利视频 | 亚洲视频一区在线观看 | 91社区视频 | 国产日韩精品在线 | 欧美精品一区二区三区在线 | 成人影院免费视频 | 国产成人精品免费视频大全最热 | 亚洲va欧美va人人爽午夜 | 中文字幕99| 国产a区| 成人乱人乱一区二区三区软件 | 美女久久| 九九色综合 | 91人人在线 | 91九色婷婷 | 99视频免费看 | 黄色免费网站在线看 | 久久国际精品 | 精品成人在线 | 欧美激情a∨在线视频播放 成人免费共享视频 | 黄色一级大片在线免费看产 | 亚洲成人自拍 | 中文字幕第十一页 | 99爱在线免费观看 | 成人国产精品一级毛片视频毛片 | 成人毛片在线视频 | a爱视频 | 国产精品久久久久久久久久久免费看 | 久久久99精品免费观看 | 日本不卡免费新一二三区 | 亚洲一区二区三区视频 | 日韩色视频 | 四虎最新地址 | 精品视频一区二区三区在线观看 | 伊人在线视频 | 成人福利网 | 久久91av| 啪啪综合网| 成人精品久久 | www.亚洲免费 |