網站首頁 編程語言 正文
前言:
想象一下,有一個服務提供個多個客戶端調用,但不是所有客戶端都需要全部的返回參數:
?比如商品列表服務返回商品的所有信息,而訂單服務調用商品列表服務,但它其實只需要商品的編碼和名稱就夠了。?
當然,我們可以為這個需求單獨創建一個服務,但是這樣不太靈活,比如又需要商品的編碼和分類的時候怎么辦?
但是,大而全的服務方法會導致計算和傳輸成本可能很高,如果我們能夠了解響應中哪些字段不需要提供給調用者,從而避免進行不必要的計算和傳輸,這對提高服務性能通常是非常有益的。
在實現 gRPC 服務時,我們可以使用?protobuf FieldMask
?實現上述功能。
一.FieldMask
默認情況下,gRPC 使用 protobuf
作為其接口定義語和數據序列化協議。
FieldMask 是一個 protobuf
消息,包含一個名為 paths 的字段,用于指定用于指定讀取操作返回或更新操作修改的字段:
message FieldMask { ? repeated string paths = 1; }
下面,讓我們看一個例子,如何在C# gRpc
服務中使用它。
二、Demo
?1.定義 .proto 文件?
在 .proto 文件中定義服務和消息:
syntax = "proto3"; option csharp_namespace = "GrpcService2"; import "google/protobuf/field_mask.proto"; package greet; // The greeting service definition. service Greeter { ? // Sends a greeting ? rpc SayHello (HelloRequest) returns (HelloReply); } // The request message containing the user's name. message HelloRequest { ? string name = 1; ? google.protobuf.FieldMask field_mask = 2; } // The response message containing the greetings. message HelloReply { ? string message1 = 1; ? string message2 = 2; ? string message3 = 3; ? string message4 = 4; ? string message5 = 5; }
關鍵點是下面2句:
// 引用 field_mask 消息 import "google/protobuf/field_mask.proto"; //定義請求字段 google.protobuf.FieldMask field_mask = 2;
?2.實現服務端?
服務端代碼如下,返回了5個字段:
public class GreeterService : Greeter.GreeterBase { ? ? private readonly ILogger_logger; ? ? public GreeterService(ILogger logger) ? ? { ? ? ? ? _logger = logger; ? ? } ? ? public override Task SayHello(HelloRequest request, ServerCallContext context) ? ? { ? ? ? ? var reply = new HelloReply ? ? ? ? { ? ? ? ? ? ? Message1 = "Hello " + request.Name + ",這是第1條消息", ? ? ? ? ? ? Message2 = "Hello " + request.Name + ",這是第2條消息", ? ? ? ? ? ? Message3 = "Hello " + request.Name + ",這是第3條消息", ? ? ? ? ? ? Message4 = "Hello " + request.Name + ",這是第4條消息", ? ? ? ? ? ? Message5 = "Hello " + request.Name + ",這是第5條消息" ? ? ? ? }; ? ? ? ? return Task.FromResult(reply); ? ? } }
?3.實現客戶端?
客戶端代碼如下:
using var channel = GrpcChannel.ForAddress("https://localhost:5001"); var client = new Greeter.GreeterClient(channel); FieldMask fieldMask = new FieldMask(); fieldMask.Paths.AddRange(new string[] { "message2", "message4" }); var request = new HelloRequest { Name = "My IO" }; request.FieldMask = fieldMask; var reply = await client.SayHelloAsync(request); ? ? ? ? ? ? Console.WriteLine($@"Greeting:? {reply.Message1} {reply.Message2} {reply.Message3} {reply.Message4} {reply.Message5} " );
傳入了 FieldMask
,這里只需要 message2
、message4
字段。
運行程序,發現有問題,還是返回了所有字段:
?4.修改服務端?
這其實是在服務端沒有判斷 fieldMask,修改服務端代碼:
var mergedReply = new HelloReply(); request.FieldMask.Merge(reply, mergedReply); return Task.FromResult(mergedReply);
結論:
在本文中,我們看到了如何使用 FieldMask ,這里僅僅是控制不返回字段,大家可以自行實現其他邏輯。
原文鏈接:https://blog.51cto.com/MyIO/5063206
相關推薦
- 2023-04-24 如何修改Linux內核參數vm.swappiness_Linux
- 2022-08-16 C#工程建立后修改工程文件名與命名空間操作_C#教程
- 2022-11-04 go語言中布隆過濾器低空間成本判斷元素是否存在方式_Golang
- 2023-02-02 一文教你利用Python制作一個生日提醒_python
- 2022-10-24 Python?NumPy教程之數據類型對象詳解_python
- 2022-11-29 redis配置文件詳解
- 2022-09-21 python?paramiko連接ssh實現命令_python
- 2022-06-16 ASP.NET?Core?6.0?添加?JWT?認證和授權功能_實用技巧
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支