The goal of this project is to generates a REST gateway wrapper layer for a grpc server with minimal customization, along with swagger
definitions conforming to OpenAPI 2.0
.
The gRPC-gateway
(https://github.com/grpc-ecosystem/grpc-gateway) is a plugin of the Google protocol buffers compiler protoc. It reads protobuf service definitions and generates a reverse-proxy server which translates a RESTful HTTP API into gRPC.
This repo, the grpc-gateway-wrapper
is a python library and executable that builds a go
binary that encapsulates the reverse proxy server along with swagger
definitions conforming to OpenAPI 2.0
.
python setup.py bdist_wheel
pip install grpc-gateway-wrapper
python -m grpc_gateway_wrapper
or:
grpc-gateway-wrapper
(it should be installed on the system path).
This is the main entrypoint script which can generate a working gRPC gateway server that can proxy between an equivalent REST API and a set of gRPC services.
╰$ python -m grpc_gateway_wrapper --help
optional arguments:
-h, --help show this help message and exit
--proto_files PROTO_FILES [PROTO_FILES ...], -p PROTO_FILES [PROTO_FILES ...]
The proto file to generate from
--working_dir WORKING_DIR, -w WORKING_DIR
Location for intermediate files. If none, random will be generated
--no_cleanup, -c Don't clean up working dir
--output_dir OUTPUT_DIR, -o OUTPUT_DIR
Location for output files
--metadata [METADATA ...], -m [METADATA ...]
gRPC metadata name(s) to add to the swagger
--install_deps, -d Install go dependencies if they're missing
--gateway_version GATEWAY_VERSION, -g GATEWAY_VERSION
Version of the grpc-gateway tools to install if installing dependencies
--log_level LOG_LEVEL, -l LOG_LEVEL
Log level for informational logging
There are additional go
dependencies which the library needs which you can directly install by passing the --install_deps
argument.
To build a gateway for your server, you need to collect the full set of proto
files used to create the server interface, including files containing type definitions (the script is not smart enough to find them for you). With that, simply call grpc_gateway_wrapper
with the --protos
argument. For example:
python -m grpc_gateway_wrapper \
--proto_files example/sample-messages.proto example/sample-service.proto
Some gRPC APIs rely on the presence of certain metadata entries (e.g. kserve model-mesh requires the mm-model-id
or mm-vmodel-id
header). These headers are not represented in the proto
file, so they're not automatically represented in the swagger
API generated by this template. In order to add them, you can use the --metadata
argument to grpc_gateway_wrapper
. For example:
python -m grpc_gateway_wrapper \
--proto_files example/sample-messages.proto example/sample-service.proto \
--metadata foo bar:default_value
Once you build the gateway using the commands above, a build
directory will be generated with the contents:
build
├── app
└── swagger
The generated binary
is the app
, along with the swagger
directory along side it.
To see the flags that can be passed to the built binary, you can run:
╰$ ./build/app --help
Usage of ./build/app:
-mtls_client_ca="": CA certificate to use to enable mutual TLS
-proxy_cert="": Cert to use when making the proxy rpc call
-proxy_cert_hname="": Hostname override for proxy cert
-proxy_endpoint="localhost:8004": Endpoint for the server being proxied to
-proxy_no_cert_val=false: Ignore certificate validation
-serve_cert="": Public cert to use when serving proxy calls
-serve_key="": Private key to use when serving proxy calls
-serve_port=8080: Port to serve the gateway on
-swagger_path="/swagger": Absolute path to swagger assets
You can run it anywhere (locally, or within a deployment) and simply point it at the running gRPC
server:
./build/app \
--swagger_path $PWD/build/swagger \
--proxy_endpoint localhost:8004 \
--serve_port 8080
(TODO - add TLS specific example)
Once a gateway is running, you can access it directly using any HTTP client you like (curl
, postman
, etc...). You can also visit its swagger documentation by hitting the /swagger
endpoint (e.g. http://localhost:8080/swagger
).
This project relies heavily on a few external libraries.
grpc-gateway
: This project provides the guts of the gateway implementation, as well as the swagger spec generationgoogle api service
: In order to avoid forcing annotations into the protobuf files, this project side-loads the REST spec using thegoogle api service
definition.