protoc-gen-grpc-gateway-ts - Clean, Idiomatic TypeScript for grpc-gateway
protoc-gen-grpc-gateway-ts
is a TypeScript client generator for the grpc-gateway
project.
It generates idiomatic TypeScript clients that connect the web frontend and golang gRPC backend fronted by grpc-gateway
.
Background
In Cash App, we prefer gRPC as the way of communication. We also use grpc-gateway
to expose our gRPC services to legacy and web clients over HTTP/1.
This worked well until the day we needed to start integrating grpc-gateway
with Web clients. To build a Web client for a gRPC enabled service, there are two options.
-
Use
protoc-gen-openapiv2
(previouslyprotoc-gen-swagger
) to generate an OpenAPI schema then run an OpenAPI generator to get the Web client -
Use
grpc-web
with envoy grpc-web filter to pipe the request through.
Although both are valid options and have reasonable numbers of users, after some investigation both options have their own pain points.
Pain points
protoc-gen-openapiv2
OpenAPI has both popularity and maturity. However, going down this path means
-
proto -> OpenAPI -> Typescript
-
Generated clients only support unary gRPC calls, where
grpc-gateway
can do server side streaming.
grpc-web
grpc-web
is a Javascript implementation of gPRC for browsers. To use it, we found:
grpc-web
client requires either a proxy, or envoy with a filter in between to do the translation.- The proxy is an extra layer for our service while we have
grpc-gateway
already - For the envoy + filter option it was not easy to set up.
- The proxy is an extra layer for our service while we have
- The generated
grpc-web
client is verbose and hard to use.- Setter is required for every desired field and there is no way to simplify it.
- TypeScript support
- It is experimental
- 3 assets files(1
.js
& 2.ts
files) generated for a single proto file. Here is an example of thegrpc-web
proto generation output.
Solution
To solve the pain points found in both protoc-gen-openapiv2
& grpc-web
, we build protoc-gen-grpc-gateway-ts
.
It comes with the following features:
- Idiomatic TypeScript clients and messages
- Single step - proto -> TypeScript
- Supports both unary calls and server side streaming
- POJO message construction guarded by message type definitions.
- Standard protoc plugin that can be run alongside any other plugins
After the creation of protoc-gen-grpc-gateway-ts
, we have
- Battle tested against 1000s of proto files in Cash App & Square for proto generation.
- Used the generated code extensively for our internal web admin modules, giving the following benefits:
- POJO message construction greatly simplifies the process to make a request, a simple request can be one liner.
- TypeScript is widely supported in main-stream IDEs, code completion, documentation flows naturally to help out daily development
- The ability to do server side streaming means the Web client is feature parity with all other clients.
- Is gaining more and more traction across internal teams
Here is an example of a simple counter service
The proto file:
// file: counter.proto
message Request {
int32 counter = 1;
}
message Response {
int32 result = 1;
}
service CounterService {
rpc Increment(Request) returns (Response);
}
Generated TypeScript file:
// file: counter.pb.ts
import * as fm from "./fetch.pb"
export type Request = {
counter?: number
}
export type Response = {
result?: number
}
export class CounterService {
static Increment(req: UnaryRequest, initReq?: fm.InitReq): Promise<UnaryResponse> {
return fm.fetchReq<UnaryRequest, UnaryResponse>(`/main.CounterService/Increment`, {...initReq, method: "POST", body: JSON.stringify(req)})
}
}
Example usage of the generated counter.pb.ts
import {CounterService} from './counter.pb'
// increase the given number once
async function increase(base: number): Promise<number> {
const resp = await CounterService.Increase({counter: base})
return resp.result
}
Open Sourcing
It was originally planned to be open-sourced via Square/Cash App’s public Github account.
However, with the help from Google Engineers, it now lives in an ideal location: grpc-ecosystem
, which is next to grpc-gateway
.
End Note
It’s a fun and resourceful journey to create protoc-gen-grpc-gateway-ts
. Hope it soon will start getting traction and contributions around the globe.