
A Grpc Gateway Tutorial and Best Practices is essential for any developer looking to improve the performance and scalability of their services.
Grpc Gateway is a reverse proxy that allows you to expose a gRPC service as a RESTful API. It's a powerful tool that can help you modernize your architecture.
To get started with Grpc Gateway, you'll need to install the grpc-gateway package using npm or yarn. This will give you access to the gRPC Gateway CLI tool.
The CLI tool allows you to generate gRPC stubs and API definitions, making it easier to create your gRPC services.
Protobuf and Service
You can define your gRPC service using protocol buffers.
This is done by creating a .proto file to define your gRPC service and messages, and adding annotations to map gRPC methods to HTTP endpoints.
To get started, create a .proto file, such as proto/hello.proto, using the following commands.
This will help you define the services and messages that are available for your project.
Related reading: C# Grpc Service
A service is defined using the service keyword, and rpc defines the functionality of the service.
For example, the Greeter service provides a SayHello function that requires input HelloRequest message and output a HelloResponse message.
You can add custom HTTP to gRPC transcoding details using the google.api.http annotation.
This is done by adding the HTTP->gRPC mapping you want, such as mapping POST /v1/message to your SayHello RPC.
Here's an example of how to define a service with HTTP to gRPC transcoding:
- (8) service keyword defines a service, and rpc defines the functionality of the service.
- (11) Adds the custom google.api.http HTTP to gRPC transcoding details.
- (12) Declares that this gRPC method transcodes to the HTTP POST method and the path /v1/message.
- (13) Declares the body schema of the HTTP request.
When you use protocol buffers, each RPC must define the HTTP method and path using the google.api.http annotation.
This will help you map gRPC methods to HTTP endpoints.
You can use the go, go-grpc, and go-gateway plugins to generate Go types and gRPC service definitions.
This will output generated files relative to the proto folder, and use the paths=source_relative option to generate files in the same directory as the source .proto file.
Here's an interesting read: When to Use Grpc
Generating Code
Generating code is a crucial step in setting up a gRPC gateway. You'll need to get the gRPC gateway plugin, which can be done by running a command that downloads the necessary tool.
To use this plugin, you'll need to update your protoc invocation to include it. This involves adding a flag to your command to enable the plugin.
Your proto file will also need to be modified to include the necessary annotations for the gRPC gateway. This will generate a new file, activity.pb.go, which can be used to build a standalone gRPC proxy in GoLang.
Here are the ways to generate code:
Running the command to generate code will produce the necessary files, including Go models, gRPC stubs, the HTTP reverse proxy, and OpenAPI documentation (if configured).
Reverse Proxy
You can run both gRPC and RESTful/JSON services on the same port using the cmux package, which differentiates between the protocol used.
To enable this, you'll need to use the cmux package to split the gRPC traffic and RESTful/JSON traffic.
Here are the possible ways to generate a reverse proxy using protoc-gen-grpc-gateway:
- Use the default mapping to HTTP semantics (method, path, etc.)
- Make additional .proto modifications to use a custom mapping
- Use an external configuration file without modifying the .proto file
The generate_unbound_methods option should be enabled when executing the plugin for the last option.
Here's an example of what a buf.gen.yaml file might look like with this option enabled:
With protoc (just the grpc-gateway stubs):
```
generate_unbound_methods: true
```
By enabling this option, you can generate the necessary code for the reverse proxy without modifying the .proto file.
You might like: Aws Upload File to S3 Api Gateway Typescript
Configuration and Customization
With gRPC Gateway, you have the flexibility to customize your API endpoints to fit your needs. By default, keys in your response are in camelCase, but you can change this by editing the Marshaler configuration.
You can also customize the behavior of your API endpoints by enabling or disabling query parameters, which is a great way to streamline your API.
Enabling or disabling query parameters is just one of the many features of gRPC API Gateway. Here are some of the other ways you can control API endpoint behavior:
- Using aliases for query parameters
- Renaming path parameters
- Fine-tuning tags, operation names, examples, custom fields, and more in OpenAPI
- Managing streaming modes (WebSocket, SSE, and Chunked-Transfer)
- Precise control over requiredness and nullability
- Utilizing global and relative external configuration files (YAML or JSON)
These features give you a high degree of control over your API endpoints, allowing you to tailor them to your specific use case.
Security and TLS
To establish a secure connection between your gRPC gateway and client, you'll want to use Transport Layer Security (TLS). TLS uses public-key cryptography and a certification authority to validate the identities of the two parties.
For a self-signed certificate authority, you can use CloudFlare's CFSSL, which I've found to be a reliable tool. CFSSL generates a CA and uses it to create a certificate for your service.
When creating your certificate, specify the hosts it's valid for and the encryption algorithm to use. I've found it helpful to define a one-year expiry period, which CFSSL uses when creating the server certificate.
Discover more: Azure Application Gateway Backend Settings Certificate
Generating TLS Certs
Generating TLS certs can be a complex process, but it's essential for establishing a secure connection between two parties. TLS uses public-key cryptography to establish this connection.
Transport Layer Security (TLS) relies on a certification authority to validate the identity of the parties involved. CloudFlare's CFSSL is a popular tool for generating self-signed certificates.
To get started, you'll need to install CFSSL. This will give you the necessary tools to create a self-signed certificate authority.
A certificate signing request (CSR) is the next step in the process. This request outlines the details of the certificate you want to create.
When creating the CSR, you'll need to define the CA's signing policies. This includes setting the expiry period, such as a one-year expiry of 8760h.
You'll also need to specify which hosts the certificate is valid for and what encryption algorithm to use. For example, you might specify a particular host and encryption algorithm.
With these details in place, you can generate your CA private key and certificate. You'll also need to create your private server key and certificate.
Suggestion: V2ray Tls Grpc
TLS on Client
To set up TLS on a client, you'll need to tell it to use a TLS connection. This can be done by configuring the client to use TLS.
You can also tell the client not to verify the certificate, which is useful when working with one-off certificate authorities. This can be done by disabling certificate verification.
However, a better approach is to make all your internal services aware of your certificate authority. This way, the client and server can communicate securely over TLS.
A different take: Grpc New Client
Error Handling and Logging
gRPC gateways already come with built-in error handling that maps gRPC error codes to HTTP status codes used by the client. This includes mapping well-known gRPC codes to HTTP status codes, such as InvalidArgument being converted to 400 (bad request).
To handle custom error requirements, you can use the WithErrorHandler option that takes an error handler function. This function gets several arguments, including the request and response writer, and the error sent by the gRPC service.
Here's a simple example of using WithErrorHandler to change the HTTP status for the request to 400 when an error occurs, irrespective of the error. This is done by creating a new error and passing it to DefaultHTTPErrorHandler, which performs a lot of work under the hood to convert the error to a valid JSON response.
gRPC gateways also provide a sophisticated error handling mechanism that generates errors with a distinct structure, separate from gRPC service errors. This clear separation allows for greater flexibility in implementing custom error management strategies, ensuring that error responses are both meaningful and actionable for external API consumers.
To log incoming and outgoing requests, you can use middleware with a gRPC gateway-generated proxy. This can be done by extracting information related to an HTTP request from *Request and the information about the response is extracted using the httpsnoop package.
Adding Logging
Adding logging to your application is crucial for debugging and issue resolution. You can use middleware with a gRPC gateway-generated proxy to achieve this.
ServerMux implements the Handler interface, allowing you to use any middleware to wrap the ServerMux and log incoming and outgoing requests. This includes middleware for logging.
To create a logging middleware, you can extract information from the *Request using the httpsnoop package. The withLogger method wraps the Handler interface and calls snoop to extract information.
The httpsnoop package under the hood calls the ServerHTTP method, which is no different from any other handler in the Go ecosystem. This means any middleware available will also work with a gRPC gateway-generated reverse proxy.
Error Handling
Error handling is a crucial aspect of building robust applications. gRPC gateways come with built-in error handling capabilities that automatically map well-known gRPC error codes to HTTP status codes.
For example, InvalidArgument is converted to a 400 (bad request) HTTP status code. You can check the complete list of mappings by following this link.
Custom error handling requirements can be met by using the WithErrorHandler option. This option takes an error handler function that gets passed all errors with the request-and-response writer.
The error handler function receives several arguments, including the context, server mux, marshaler, writer, request, and error. Here's a simple example of using WithErrorHandler to change the HTTP status to 400 when an error occurs.
DefaultHTTPErrorHandler performs a lot of work under the hood to convert the error to a valid JSON response, making it a convenient option to use wherever possible.
Check this out: Azure App Gateway Cutom Error Pages
HTTP and Metadata
HTTP and Metadata is a crucial aspect of gRPC gateway. gRPC and Restful/JSON pass metadata differently, with gRPC abstracting out sending metadata using a metadata interface depending on the language used.
gRPC gateway provides a simple mapping interface to convert gRPC metadata to HTTP headers and vice versa. This interface allows for two different methods to handle header-to-metadata conversion: WithOutgoingHeaderMatcher and WithMetadata. WithOutgoingHeaderMatcher converts metadata into HTTP headers, while WithMetadata extracts incoming HTTP headers and sends them to the gRPC service in metadata.
Here are the two methods used for header-to-metadata conversion:
This allows developers to customize the mapping of HTTP headers to gRPC metadata, making it easier to integrate gRPC services with HTTP clients.
A unique perspective: Grpc over Http
HTTP Headers and Metadata
HTTP headers and metadata play a crucial role in communication between the gRPC gateway and clients. gRPC abstracts out sending metadata by providing a metadata interface depending on the language used.
The gRPC gateway provides a simple mapping interface to convert gRPC metadata to HTTP headers and vice versa. This interface allows for two different methods to handle header-to-metadata conversion.
WithOutgoingHeaderMatcher handles the header going from the gRPC gateway back to the client, converting metadata into HTTP headers. It takes a string and returns true if the header is passed to the client, or false if not.
WithMetadata handles incoming HTTP headers, extracting them to be sent to the gRPC service in metadata. Its most common use case is to get an authentication token and pass it to metadata.
Here are the two methods for handling header-to-metadata conversion:
These methods allow for customization of the mapping of HTTP headers to gRPC metadata, which is a key feature of the gRPC gateway.
Runtime Registration and HTTP Serving

In the runtime registration and HTTP serving phase, you utilize the generated HTTP handlers to manage HTTP traffic. gRPC API Gateway offers a lightweight HTTP handler compatible with the standard library's http package to serve HTTP requests.
Developers can tailor various behaviors, including error translation, custom marshalling, WebSocket connection upgrades, and header to metadata mapping. These customizations enable you to handle HTTP requests in a way that suits your application's needs.
To start the application, you can use the generated HTTP handlers to handle HTTP requests. The gRPC Gateway centralizes common elements of the reverse proxy, utilizing the generated HTTP handlers to handle the specific translations required for different endpoints and service calls.
Here are some key benefits of using gRPC API Gateway for runtime registration and HTTP serving:
- Error Translation: Customize the structure of HTTP errors or implement different error handling strategies.
- Custom Marshallers: Implement custom marshallers for various content types, such as XML or YAML.
- WebSocket Connection Upgrades: Manage WebSocket connection upgrades to support real-time communication.
- Header to Metadata Mapping: Customize the mapping of HTTP headers to gRPC metadata.
By using gRPC API Gateway, you can create a unified interface for handling HTTP and gRPC requests, making it easier to manage your application's traffic and improve its overall performance.
Streaming and Architecture
gRPC Gateway's streaming capabilities are a game-changer for real-time applications. It supports Server-Sent Events (SSE), which provides a standardized method for receiving push notifications from servers.
With SSE, developers can simplify the implementation of real-time updates and notifications in web applications without the complexity of WebSocket setup. This makes it easier to build web applications that require real-time updates.
gRPC Gateway also offers full support for bidirectional communication through WebSockets, which facilitates true real-time applications with persistent connections. This effectively bridges gRPC's bidirectional streaming capabilities to web clients that cannot directly use gRPC.
Here's a summary of gRPC Gateway's streaming features:
- SSE (Server-Sent Events) for server-to-client streaming over HTTP
- WebSocket Integration for bidirectional communication
Streaming Mode Functionality
gRPC API Gateway supports two primary streaming modes: Server-Sent Events (SSE) and WebSocket Integration.
In SSE, server-to-client streaming is enabled using the EventSource API, providing a standardized method for receiving push notifications from servers.
This simplifies the implementation of real-time updates and notifications in web applications without the complexity of WebSocket setup.
Additional reading: Websocket Api Gateway Permission

For WebSocket Integration, full support is offered for bidirectional communication, facilitating true real-time applications with persistent connections.
This effectively bridges gRPC's bidirectional streaming capabilities to web clients that cannot directly use gRPC.
Here's a breakdown of the general approach for handling long-lived connections in streaming modes:
Technical Architecture
In a streaming architecture, the technical architecture plays a crucial role in ensuring seamless data flow.
gRPC API Gateway operates through two distinct phases: code generation and HTTP endpoint registration at runtime. This approach enables efficient and scalable communication between services.
Prerequisites and Setup
To get started with grpc gateway, you'll need to create a directory on your local machine called grpc-gateway for your project from the terminal.
This directory will serve as the foundation for your project, so make sure to create it in the right location.
Open the folder by running the following command with Visual Studio Code to begin working on your project.
Create a main.go file and initialize your local project by running the following Go command to set up your project's structure.
You'll need to install some tools to work with grpc gateway, so use go get to download the required packages.
These dependencies will be recorded in the go.mod file, which was created by the previous command, and will be used to generate the stubs.
Make sure to add $GOPATH/bin to your $PATH so that executables installed via go get are available on your $PATH.
Your project folder will look like this after running the commands.
If this caught your attention, see: Aws Upload File to S3 Api Gateway
Testing and Examples
You can test the service by sending a request to the HTTP gateway, which will invoke the AddUser gRPC method via the HTTP reverse proxy.
To run the gateway example, start the server with the command "go run server/main.go". Then use cURL to send HTTP requests to the gateway.
The examples directory contains more examples, including service definitions in files such as "proto/examplepb/echo_service.proto" and service implementations in files like "server/main.go". You can also use custom HTTP handlers, such as serving swagger.json, by checking out an example by CoreOS.
Step 6: Test Service

Now that you've set up the service, it's time to test it. You can send a request to the HTTP gateway to invoke the AddUser gRPC method via the HTTP reverse proxy.
Start the server by running the gateway example. This will make the service available for testing.
Use cURL to send HTTP requests to the gateway. This is a quick and easy way to test the service and see if it's working as expected.
More Examples
You can find more examples of gRPC services and implementations in the examples directory. These examples demonstrate how to define services, implement them, and create entrypoints for generated reverse proxies.
The examples directory contains several .proto files that define gRPC services, including echo_service.proto, a_bit_of_everything.proto, and unannotated_echo_service.proto, which all have service definitions.
The server/main.go file shows an example of service implementation, while the main.go file serves as the entrypoint for the generated reverse proxy.
If you want to use the same port for custom HTTP handlers, such as serving swagger.json, gRPC-Gateway, and a gRPC server, you can check out this example by CoreOS, along with their accompanying blog post.
Additional reading: Amazon S3 File Gateway
Kong Alternatives and Comparison
Kong gRPC-gateway is a great alternative to a proxy, especially if your gRPC service is written in a language besides Golang, or if it's not your code or your service.
You can use it as an API gateway to get an equivalent proxy setup by enabling the grpc-gateway plugin and configuring things correctly.
Kong gRPC-gateway is a versatile solution that allows you to interact with your gRPC service from the outside without worrying about the implementation details.
It's a great solution if you're not the original developer of the gRPC service, as you can still use it without needing to know the internal workings.
By using Kong gRPC-gateway, you can achieve a similar proxy setup to the one mentioned earlier.
Related reading: Grpc Proxy
Featured Images: pexels.com

