当前位置: 首页 > news >正文

前端API设计:gRPC Web实战指南

前端API设计:gRPC Web实战指南

前言

gRPC是Google推出的高性能、开源的远程过程调用(RPC)框架。gRPC Web是gRPC的Web版本,它允许浏览器直接与gRPC服务通信。今天我就来给大家详细介绍gRPC Web的使用方法。

什么是gRPC Web

gRPC Web是一个允许Web客户端直接调用gRPC服务的协议。它基于HTTP/2协议,提供了高效的双向通信能力。

gRPC Web的核心优势

const grpcWebAdvantages = [ '高性能:基于HTTP/2协议', '类型安全:使用Protocol Buffers', '双向流支持', '代码自动生成', '跨语言支持' ];

gRPC Web工作原理

# gRPC Web架构 Web Client ↔ Envoy Proxy ↔ gRPC Server 1. Web客户端发送HTTP/1.1请求 2. Envoy代理将请求转换为HTTP/2 3. 转发到gRPC服务器 4. 服务器响应通过Envoy返回给客户端

gRPC Web实战

1. 定义Protocol Buffers

// user.proto syntax = "proto3"; package user; service UserService { rpc GetUser(GetUserRequest) returns (User) {} rpc GetUsers(GetUsersRequest) returns (stream User) {} rpc CreateUser(CreateUserRequest) returns (User) {} rpc UpdateUser(UpdateUserRequest) returns (User) {} rpc DeleteUser(DeleteUserRequest) returns (Empty) {} } message User { string id = 1; string name = 2; string email = 3; int32 age = 4; } message GetUserRequest { string id = 1; } message GetUsersRequest { int32 page = 1; int32 limit = 2; } message CreateUserRequest { string name = 1; string email = 2; int32 age = 3; } message UpdateUserRequest { string id = 1; optional string name = 2; optional string email = 3; optional int32 age = 4; } message DeleteUserRequest { string id = 1; } message Empty {}

2. 生成代码

# 安装工具 npm install grpc-web protoc # 生成JavaScript代码 protoc \ --proto_path=./proto \ --js_out=import_style=commonjs,binary:./src \ --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./src \ user.proto

3. 配置Envoy代理

# envoy.yaml static_resources: listeners: - name: listener_0 address: socket_address: { address: 0.0.0.0, port_value: 8080 } filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager codec_type: auto stat_prefix: ingress_http route_config: name: local_route virtual_hosts: - name: local_service domains: ["*"] routes: - match: { prefix: "/" } route: cluster: grpc_backend max_stream_duration: grpc_timeout_header_max: 0s http_filters: - name: envoy.filters.http.grpc_web - name: envoy.filters.http.router clusters: - name: grpc_backend connect_timeout: 0.25s type: logical_dns lb_policy: round_robin load_assignment: cluster_name: grpc_backend endpoints: - lb_endpoints: - endpoint: address: socket_address: address: localhost port_value: 9090

4. 创建gRPC客户端

// grpc-client.js import { UserServiceClient } from './user_grpc_web_pb'; import { GetUserRequest, GetUsersRequest, CreateUserRequest, UpdateUserRequest, DeleteUserRequest } from './user_pb'; const client = new UserServiceClient('http://localhost:8080'); // 获取用户 function getUser(userId) { const request = new GetUserRequest(); request.setId(userId); return new Promise((resolve, reject) => { client.getUser(request, {}, (error, response) => { if (error) { reject(error); } else { resolve(response.toObject()); } }); }); } // 获取用户列表 function getUsers(page, limit) { const request = new GetUsersRequest(); request.setPage(page); request.setLimit(limit); return new Promise((resolve, reject) => { const users = []; const stream = client.getUsers(request); stream.on('data', (user) => { users.push(user.toObject()); }); stream.on('end', () => { resolve(users); }); stream.on('error', (error) => { reject(error); }); }); } // 创建用户 function createUser(user) { const request = new CreateUserRequest(); request.setName(user.name); request.setEmail(user.email); request.setAge(user.age); return new Promise((resolve, reject) => { client.createUser(request, {}, (error, response) => { if (error) { reject(error); } else { resolve(response.toObject()); } }); }); }

5. 在React中使用

import { useState, useEffect } from 'react'; import { getUser, createUser } from './grpc-client'; function UserProfile({ userId }) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { async function fetchUser() { try { setLoading(true); const userData = await getUser(userId); setUser(userData); setError(null); } catch (err) { setError(err.message); } finally { setLoading(false); } } fetchUser(); }, [userId]); if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error}</div>; return ( <div> <h1>{user.name}</h1> <p>Email: {user.email}</p> <p>Age: {user.age}</p> </div> ); }

gRPC Web高级特性

1. 双向流

// 双向流示例 function chatStream() { const stream = client.chat(); stream.on('data', (message) => { console.log('Received:', message.toObject()); }); stream.on('end', () => { console.log('Stream ended'); }); // 发送消息 const message = new ChatMessage(); message.setContent('Hello'); stream.write(message); // 关闭流 stream.close(); }

2. 错误处理

// 错误处理示例 async function safeGetUser(userId) { try { const user = await getUser(userId); return user; } catch (error) { if (error.code === 5) { console.error('权限不足'); } else if (error.code === 3) { console.error('参数错误'); } else if (error.code === 14) { console.error('服务器不可用'); } throw error; } }

3. 元数据传递

// 设置请求元数据 const metadata = { 'Authorization': 'Bearer token', 'X-Request-Id': 'abc123' }; client.getUser(request, metadata, (error, response) => { // ... });

gRPC Web与REST对比

# gRPC Web vs REST对比 | 特性 | gRPC Web | REST | |------|----------|------| | 协议 | HTTP/2 | HTTP/1.1 | | 数据格式 | Protocol Buffers | JSON | | 性能 | 高 | 一般 | | 类型安全 | 是 | 否 | | 代码生成 | 自动 | 手动 | | 双向流 | 支持 | 有限 | | 学习曲线 | 高 | 低 |

gRPC Web最佳实践

1. 使用Protocol Buffers

# Proto文件组织 proto/ user.proto post.proto common.proto

2. 代码生成脚本

{ "scripts": { "generate": "protoc --proto_path=./proto --js_out=import_style=commonjs,binary:./src --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./src user.proto" } }

3. 错误处理

// 统一错误处理 class GrpcError extends Error { constructor(code, message) { super(message); this.code = code; this.name = 'GrpcError'; } }

总结

gRPC Web提供了一种高性能、类型安全的API调用方式:

  1. 高性能:基于HTTP/2协议,支持多路复用
  2. 类型安全:使用Protocol Buffers定义接口
  3. 代码生成:自动生成客户端代码
  4. 双向流:支持实时通信

如果你需要高性能的API调用,gRPC Web是一个很好的选择!

核心要点

  • 定义清晰的Protocol Buffers
  • 使用Envoy代理
  • 自动生成客户端代码
  • 合理处理错误

希望这篇文章能帮助你掌握gRPC Web!

http://www.jsqmd.com/news/810150/

相关文章:

  • claud 配置指南
  • 2026年口碑最佳新风系统厂家,打造清新家居环境首选
  • 靠谱的工程防火门公司推荐
  • 【PCB设计进阶篇之阻抗工具】告别SI9000?盘点新一代阻抗计算与协同设计工具
  • 【开发者实践】HarmonyOS 6.1.0 创新特性“悬浮页签+沉浸光感”精品文章专题
  • 重构电梯装饰美学价值,鼎钻钢业(佛山)摆脱同质化内卷的核心路径 - 资讯焦点
  • 别急着抛弃 Workflow:强大的 Agent 也有搞不定的场景
  • 如何每天节省20分钟:淘宝淘金币自动化脚本的完整使用指南
  • Perplexity×NEJM文献交叉验证协议(NIH资助项目内部文档首次公开:含4层可信度打分矩阵与人工校验SOP)
  • VRM-Addon-for-Blender深度解析:Blender中VRM格式的完整技术解决方案
  • SAP EWM拣货队列实战:从后台配置到RF手持端操作全解析
  • 配置OpenClaw使用Taotoken作为其AI模型供应商的详细步骤
  • 多模态大语言模型(MLLM)核心技术解析与实践指南
  • 2026最权威的AI辅助写作方案推荐
  • 内容创作团队如何借助Taotoken调用不同模型优化文案生成效果
  • Java场景面试宝典
  • 别再复制粘贴了!手把手教你用MATLAB/Simulink从传递函数到C代码实现低通滤波器
  • 2026 北京央国企报名培训选型指南 靠谱报考渠道推荐 - 资讯焦点
  • Carla 启动卡在75%并报“Fatal error”:从崩溃日志到资源缺失的排查实录
  • 从过拟合到模型选择:VC维理论如何帮你避开深度学习的坑?
  • 如何快速自动化淘宝任务:从零开始的淘金币脚本完整指南
  • 如何轻松解锁Cursor Pro完整功能:一键激活与无限使用的完整指南
  • 如何零安装体验Windows 12?这个在线模拟器让你3秒上手
  • 大模型架构已到尽头?小白也能看懂的核心演进与收藏技巧!
  • PCB与结构件接触面外围1mm白油丝印覆盖的原理及原因
  • 仅限内部测试者知晓:Midjourney未公开的--detail boost隐式指令(实测使睫毛/织物/金属反光细节识别率提升3.2倍)
  • 官方认证|2026年贵州五大正规伴手礼供应商排名,贵阳息烽等地黄南武阳朗辣子鸡口碑稳居行业前列 - 十大品牌榜
  • 魔兽争霸3游戏体验全面优化指南:WarcraftHelper一站式解决方案
  • 英雄联盟全能工具箱:从新手到高手的完整进阶指南
  • DeepSeek V3 API正式GA前最后兼容指南:3类废弃Endpoint迁移路径、2种向后兼容降级策略与1套自动化检测脚本