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

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

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

01介紹

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

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

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

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

02gRPC-Gateway

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

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

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

首先,我們需要先搭建一個 Go 環境。

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

使用 go mod init 工具創建一個 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 實戰

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

創建 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

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

編寫剩余 Go 代碼

創建 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"
};
}
}
...

關于 HTTP 和 gRPC 映射的更多內容,可以參閱 Google API 文檔。

生成 gRPC-Gateway 存根

現在,我們已將 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

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

創建 grpc-gateway 目錄,并創建 main.go 文件,創建 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

響應結果:

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

04總結

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

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

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

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

圖片來自 gRPC-Gateway 官方文檔


責任編輯:武曉燕 來源: Golang語言開發棧
相關推薦

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

開發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客戶端

2025-02-04 13:53:18

NixGogRPC

2023-03-28 07:03:15

gRPCMetadata

2023-03-02 07:20:10

GRPC服務健康檢查協議

2024-04-22 09:30:24

2024-02-05 08:50:57

Golang標準庫客戶端

2025-05-20 09:39:57

GogRPC微服務

2023-06-10 23:01:41

GrpcProtobuf數據

2023-09-06 07:17:57

2009-12-21 10:19:05

Silverlight

2023-03-05 23:11:07

Go語言服務
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文字幕乱码亚洲精品一区 | 国产最好的av国产大片 | 综合婷婷| 国产免费人成xvideos视频 | 老牛影视av一区二区在线观看 | 日韩精品一区二区三区中文在线 | 欧美一区二区大片 | 黄网站在线播放 | 亚洲日韩第一页 | 国产欧美精品区一区二区三区 | 狠狠狠干| 国产色婷婷精品综合在线手机播放 | 精品国产乱码久久久久久蜜臀 | 国产9999精品| 99re在线视频| 国产91在线播放精品91 | 伊人久久免费视频 | 日本h片在线观看 | 国产精品一区久久久久 | 精品av | 狠狠干狠狠操 | 97操操| 欧美日韩国产高清 | 欧美在线亚洲 | 黄网站免费观看 | 亚洲精品乱码久久久久久按摩观 | 国产欧美一区二区三区在线播放 | 成人午夜网站 | 亚洲一级淫片 | www.av7788.com | 国产精品伦一区二区三级视频 | 亚洲福利一区 | 最新国产精品精品视频 | 久久免费视频观看 | 午夜久久久久 | 激情欧美一区二区三区 | 综合久久久 | 亚洲精品九九 | а√中文在线8 | 亚洲欧美一区二区三区在线 | 久久久久久久久久久久久9999 |