日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Golang語(yǔ)言gRPC服務(wù)怎么同時(shí)支持gRPC和HTTP客戶端調(diào)用?

01介紹

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

成都做網(wǎng)站、網(wǎng)站建設(shè)中從網(wǎng)站色彩、結(jié)構(gòu)布局、欄目設(shè)置、關(guān)鍵詞群組等細(xì)微處著手,突出企業(yè)的產(chǎn)品/服務(wù)/品牌,幫助企業(yè)鎖定精準(zhǔn)用戶,提高在線咨詢和轉(zhuǎn)化,使成都網(wǎng)站營(yíng)銷成為有效果、有回報(bào)的無(wú)錫營(yíng)銷推廣。創(chuàng)新互聯(lián)建站專業(yè)成都網(wǎng)站建設(shè)十多年了,客戶滿意度97.8%,歡迎成都創(chuàng)新互聯(lián)客戶聯(lián)系。

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

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

02gRPC-Gateway

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

gRPC-Gateway 可幫助您同時(shí)以 gRPC 和 RESTful 風(fēng)格提供 API。

在我們開(kāi)始編碼之前,需要一些先決條件。

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

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

使用 go mod init 工具創(chuàng)建一個(gè) 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 實(shí)戰(zhàn)

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

創(chuàng)建 proto 文件

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

生成 gRPC 服務(wù)端存根

使用 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 命令工具,生成一個(gè) *.pb.go 文件和一個(gè) *_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 選項(xiàng)

gRPC-Gateway 使用 google.api.http 選項(xiàng)定義 gRPC 服務(wù)如何映射到 JSON 請(qǐng)求和響應(yīng),使用 protoc 時(shí),每個(gè) RPC 必須使用 google.api.http 選項(xiàng)定義 HTTP 方法和路徑。

因此,我們需要將 google/api/http.proto 導(dǎo)入添加到 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 選項(xiàng)添加到 proto 文件中,我們需要使用 gRPC-Gateway 生成器來(lái)生成存根。

在使用 protoc 生成存根之前,我們需要將一些依賴項(xiàng)復(fù)制到 proto 文件目錄中。將 googleapis 的子集從官方存儲(chǔ)庫(kù)下載并復(fù)制到本地 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 命令工具,生成一個(gè) *.gw.pb.go 文件。

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

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)
}
}

啟動(dòng)服務(wù)

grpc 服務(wù)

go run main.go

gRPC-Gateway

go run grpc-gateway/main.go

cURL 測(cè)試

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

響應(yīng)結(jié)果:

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

04總結(jié)

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

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

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

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


當(dāng)前文章:Golang語(yǔ)言gRPC服務(wù)怎么同時(shí)支持gRPC和HTTP客戶端調(diào)用?
轉(zhuǎn)載來(lái)源:http://www.5511xx.com/article/coghsde.html