grpc-transcode
Description#
HTTP(s) -> APISIX -> gRPC server
Proto#
Attributes#
content:.protoor.pbfile's content.
Add a proto#
Here's an example, adding a proto which id is 1:
curl http://127.0.0.1:9080/apisix/admin/proto/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{ "content" : "syntax = \"proto3\"; package helloworld; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }"}'If your .proto file contains imports, or you want to combine multiple .proto files into a proto,
you can use .pb file to create the proto.
Assumed we have a .proto called proto/helloworld.proto, which imports another proto file:
syntax = "proto3";
package helloworld;import "proto/import.proto";...First of all, let's create a .pb file from .proto files:
protoc --include_imports --descriptor_set_out=proto.pb proto/helloworld.protoThe output binary file proto.pb will contain both helloworld.proto and import.proto.
Then we can submit the content of proto.pb as the content field of the proto.
As the content is binary, we need to encode it in base64 first. Here we use a Python script to do it:
#!/usr/bin/env python# coding: utf-8# save this file as upload_pb.pyimport base64import sys# sudo pip install requestsimport requests
if len(sys.argv) <= 1: print("bad argument") sys.exit(1)with open(sys.argv[1], 'rb') as f: content = base64.b64encode(f.read())id = sys.argv[2]api_key = "edd1c9f034335f136f87ad84b625c8f1" # Change it
reqParam = { "content": content,}resp = requests.put("http://127.0.0.1:9080/apisix/admin/proto/" + id, json=reqParam, headers={ "X-API-KEY": api_key,})print(resp.status_code)print(resp.text)Create proto:
chmod +x ./upload_pb.pb./upload_pb.py proto.pb 1# 200# {"node":{"value":{"create_time":1643879753,"update_time":1643883085,"content":"CmgKEnByb3RvL2ltcG9ydC5wcm90bxIDcGtnIhoKBFVzZXISEgoEbmFtZRgBIAEoCVIEbmFtZSIeCghSZXNwb25zZRISCgRib2R5GAEgASgJUgRib2R5QglaBy4vcHJvdG9iBnByb3RvMwq9AQoPcHJvdG8vc3JjLnByb3RvEgpoZWxsb3dvcmxkGhJwcm90by9pbXBvcnQucHJvdG8iPAoHUmVxdWVzdBIdCgR1c2VyGAEgASgLMgkucGtnLlVzZXJSBHVzZXISEgoEYm9keRgCIAEoCVIEYm9keTI5CgpUZXN0SW1wb3J0EisKA1J1bhITLmhlbGxvd29ybGQuUmVxdWVzdBoNLnBrZy5SZXNwb25zZSIAQglaBy4vcHJvdG9iBnByb3RvMw=="},"key":"\/apisix\/proto\/1"},"action":"set"}Attribute List#
| Name | Type | Requirement | Default | Valid | Description |
|---|---|---|---|---|---|
| proto_id | string/integer | required | .proto content id. | ||
| service | string | required | the grpc service name. | ||
| method | string | required | the method name of grpc service. | ||
| deadline | number | optional | 0 | deadline for grpc, ms | |
| pb_option | array[string(pb_option_def)] | optional | protobuf options |
How To Enable#
Here's an example, to enable the grpc-transcode plugin to specified route:
- attention: the
schemein the route's upstream must begrpc - the grpc server example:grpc_server_example
curl http://127.0.0.1:9080/apisix/admin/routes/111 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{ "methods": ["GET"], "uri": "/grpctest", "plugins": { "grpc-transcode": { "proto_id": "1", "service": "helloworld.Greeter", "method": "SayHello" } }, "upstream": { "scheme": "grpc", "type": "roundrobin", "nodes": { "127.0.0.1:50051": 1 } }}'Test Plugin#
The above configuration proxy:
curl -i http://127.0.0.1:9080/grpctest?name=worldresponse:
HTTP/1.1 200 OKDate: Fri, 16 Aug 2019 11:55:36 GMTContent-Type: application/jsonTransfer-Encoding: chunkedConnection: keep-aliveServer: APISIX web serverProxy-Connection: keep-alive
{"message":"Hello world"}This means that the proxying is working.
Use pb_option option of grpc-transcode plugin#
option list#
enum as result
- enum_as_name
- enum_as_value
int64 as result
- int64_as_number
- int64_as_string
- int64_as_hexstring
default values option
- auto_default_values
- no_default_values
- use_default_values
- use_default_metatable
hooks option
- enable_hooks
- disable_hooks
curl http://127.0.0.1:9080/apisix/admin/routes/23 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{ "methods": ["GET"], "uri": "/zeebe/WorkflowInstanceCreate", "plugins": { "grpc-transcode": { "proto_id": "1", "service": "gateway_protocol.Gateway", "method": "CreateWorkflowInstance", "pb_option":["int64_as_string"] } }, "upstream": { "scheme": "grpc", "type": "roundrobin", "nodes": { "127.0.0.1:26500": 1 } }}'Test pb_option#
Visit configured route:
$ curl -i "http://127.0.0.1:9080/zeebe/WorkflowInstanceCreate?bpmnProcessId=order-process&version=1&variables=\{\"orderId\":\"7\",\"ordervalue\":99\}"HTTP/1.1 200 OKDate: Wed, 13 Nov 2019 03:38:27 GMTContent-Type: application/jsonTransfer-Encoding: chunkedConnection: keep-alivegrpc-encoding: identitygrpc-accept-encoding: gzipServer: APISIX web serverTrailer: grpc-statusTrailer: grpc-message
{"workflowKey":"#2251799813685260","workflowInstanceKey":"#2251799813688013","bpmnProcessId":"order-process","version":1}"workflowKey":"#2251799813685260" suggests pb_option configuration success.
Disable Plugin#
Remove the corresponding json configuration in the plugin configuration to disable grpc-transcode.
APISIX plugins are hot-reloaded, therefore no need to restart APISIX.
curl http://127.0.0.1:9080/apisix/admin/routes/111 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{ "uri": "/grpctest", "plugins": {}, "upstream": { "scheme": "grpc", "type": "roundrobin", "nodes": { "127.0.0.1:50051": 1 } }}'