如何通过HTTP/1.x(RESTful)请求调用Java gRPC服务
实现RESTful接口调用Java gRPC服务的方案
下面是几种可行的实现方式,按需选择:
1. 使用gRPC Gateway(官方推荐)
这是gRPC官方提供的转码工具,能直接把REST请求转换成gRPC请求,无需自己写太多代码。
步骤:
- 修改Proto文件:添加HTTP映射注解,把REST路径和gRPC方法绑定
syntax = "proto3"; package com.example; import "google/api/annotations.proto"; service MyGrpcService { rpc GetData(GetDataRequest) returns (GetDataResponse) { option (google.api.http) = { get: "/api/v1/data/{id}" }; } } message GetDataRequest { string id = 1; } message GetDataResponse { string content = 1; } - 生成Gateway代码:通过Maven/Gradle的Protobuf插件,配置生成grpc-gateway相关代码。比如Maven中需添加
grpc-gateway和protoc-gen-grpc-gateway依赖。 - 启动Gateway服务:编写启动类,配置gRPC服务的地址,启动后Gateway就会监听REST请求,转发给后端gRPC服务。
2. Spring Boot包装层(灵活定制)
如果需要对REST请求做额外处理(比如参数校验、权限控制),可以用Spring Boot写一层REST接口,内部调用gRPC客户端。
步骤:
- 引入依赖:添加Spring Boot和gRPC客户端依赖(比如
net.devh:grpc-spring-boot-starter) - 编写REST Controller:注入gRPC客户端,在接口方法里调用gRPC服务
@RestController @RequestMapping("/api/v1") public class RestWrapperController { private final MyGrpcServiceGrpc.MyGrpcServiceBlockingStub grpcStub; // 构造注入gRPC客户端 public RestWrapperController(MyGrpcServiceGrpc.MyGrpcServiceBlockingStub grpcStub) { this.grpcStub = grpcStub; } @GetMapping("/data/{id}") public ResponseEntity<String> getData(@PathVariable String id) { GetDataRequest request = GetDataRequest.newBuilder().setId(id).build(); GetDataResponse response = grpcStub.getData(request); return ResponseEntity.ok(response.getContent()); } } - 配置启动:在
application.yml中配置gRPC服务地址,启动Spring Boot应用即可通过REST接口访问。
3. Envoy反向代理(无代码侵入)
如果不想修改现有代码,用Envoy作为反向代理,自动完成REST到gRPC的转码。
步骤:
- 编写Envoy配置文件:配置HTTP监听、路由映射和gRPC转码规则,指定你的gRPC服务地址和proto文件路径
- 启动Envoy:用Docker运行Envoy容器,挂载配置文件和proto的二进制描述文件,即可通过Envoy的端口发送REST请求,由它转发给gRPC服务。
示例Envoy配置核心部分:
static_resources: listeners: - address: { socket_address: { address: 0.0.0.0, port_value: 8080 } } filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: route_config: virtual_hosts: - routes: - match: { path: "/api/v1/data/{id}" } route: { cluster: grpc_service } http_filters: - name: envoy.filters.http.grpc_json_transcoder typed_config: proto_descriptor: "/path/to/your/service.proto.bin" services: ["com.example.MyGrpcService"] clusters: - name: grpc_service http2_protocol_options: {} load_assignment: endpoints: - lb_endpoints: - endpoint: { socket_address: { address: localhost, port_value: 9090 } }
内容的提问来源于stack exchange,提问作者Pushpak
相关产品推荐
相关产品推荐

