For doing a server abstraction, there was a simple reason: lack of middlewares which are (almost) an essential concept to backend server development. With the client, there are no missing features per se, but the interface is a bit basic, extremely verbose and somewhat painful to work with. ProtoCat's client aims at providing a modern familiar interface, that does not take any power of the underlying layer away and preserves (or improves at some points) type safety.
Compare the following implementations that achieve the same goal with native grpc interface for node, and ProtoCat's client abstraction with
- Initialize client
- Setup request message and set client metadata
- Obtain server's response, initial and trailing metadata
While the ProtoCat's client really shines on unary calls, it does support all gRPC call types. Following the premise of keeping the power of underlying implementation, we must tamper with the stream API.
createClient accepts the same arguments as the native client, with additional first argument being a client definition:
- Address is mandatory
- Credentials are mandatory on the underlying implementation, when not supplied insecure channel credentials are provided
- Client options
The helper creates an instance in a closure and provides stub with the updated API.
Each call instead of getting arguments for
request (some types),
options, is provided a setup function, in which user can set the prepared objects.
The client definition is either a client class, or object of client classes:
This way you can have a single client to access multiple services of a single API, with sharing the connection configuration. In this case, there are several client instances created under the hood with the same configuration and the types are joyfully inferred from the definition!
Exciting feature of gRPC clients are interceptors. They are like middlewares for clients, allowing you to add hooks for your client actions. It's a powerful concept that allows for uniform caching, logging or retry mechanisms.
The native API is as always basic, verbose and powerful. For many simple use-cases too overwhelming. But since ProtoCat aims to support potentially existing intereceptors and yet provide an elegant way to define custom ones, it proves some basic creators to handle the basic use cases.
Need more? You can create your custom interceptor that ones just the thing you need. See gRPC for NodeJS Client Interceptors that has detailed overview of the specs the implementation follows.
Middleware-like interface for convenient logging
If you are required to set client metadata on each request (for example to authenticate), you can let this interceptor take care of that