@probitas/client-grpc
gRPC client for Probitas scenario testing framework.
This package provides a gRPC client with Server Reflection support, designed for
integration testing of gRPC services. It is a thin wrapper around
`@probitas/client-connectrpc` with
protocol: "grpc" pre-configured.
Features
- Native gRPC: Uses gRPC protocol (HTTP/2 with binary protobuf)
- Server Reflection: Auto-discover services and methods at runtime
- Field Name Conversion: Automatic snake_case ↔ camelCase conversion
- TLS Support: Configure secure connections with custom certificates
- Duration Tracking: Built-in timing for performance monitoring
- Error Handling: Test error responses without throwing exceptions
- Resource Management: Implements
AsyncDisposablefor proper cleanup
Installation
deno add jsr:@probitas/client-grpc
Quick Start
import { createGrpcClient } from "@probitas/client-grpc";
// Create client (uses reflection by default)
const client = createGrpcClient({
url: "http://localhost:50051",
});
// Call a method
const response = await client.call(
"echo.EchoService",
"echo",
{ message: "Hello!" }
);
console.log(response.data);
await client.close();
Service Discovery
import { createGrpcClient } from "@probitas/client-grpc";
const client = createGrpcClient({ url: "http://localhost:50051" });
// Discover available services
const services = await client.reflection.listServices();
console.log("Services:", services);
// Get method information
const info = await client.reflection.getServiceInfo("echo.EchoService");
console.log("Methods:", info.methods);
await client.close();
Field Name Conventions
The client automatically handles field name conversion between protobuf and JavaScript:
- Request: Accept both
snake_case(protobuf) andcamelCase(JavaScript) field names - Response:
response.data— Plain JSON withcamelCasefields (no$typeName)response.raw— Original protobuf Message with metadata (includes$typeName)
import { createGrpcClient } from "@probitas/client-grpc";
const client = createGrpcClient({ url: "http://localhost:50051" });
// Request: Both camelCase and snake_case work
const response = await client.call("echo.Echo", "echoWithDelay", {
message: "hello",
delayMs: 100, // camelCase (recommended for JavaScript)
// delay_ms: 100, // snake_case (protobuf style) also works
});
// Response data: JSON with camelCase fields
console.log(response.data);
// { message: "hello", metadata: {...} } ← no $typeName
// Response raw: protobuf Message with metadata
console.log(response.raw);
// { $typeName: "echo.EchoResponse", message: "hello", ... }
await client.close();
Using with using Statement
import { createGrpcClient } from "@probitas/client-grpc";
await using client = createGrpcClient({ url: "http://localhost:50051" });
const res = await client.call("echo.EchoService", "echo", { message: "test" });
console.log(res.data);
// Client automatically closed when block exits
Related Packages
| Package | Description |
|---|---|
| `@probitas/client` | Core utilities and types |
| `@probitas/client-connectrpc` | ConnectRPC client (supports Connect, gRPC, gRPC-Web) |
Links
Installation
deno add jsr:@probitas/client-grpcClasses
#GrpcError
class GrpcError extends ClientErrorClientErrorError class for ConnectRPC/gRPC errors.
Use statusCode to distinguish between different gRPC error codes.
| Name | Description |
|---|---|
name | — |
kind | — |
statusCode | — |
statusMessage | — |
metadata | — |
details | — |
Constructor
new GrpcError(
message: string,
statusCode: ConnectRpcStatusCode,
statusMessage: string,
options?: ConnectRpcErrorOptions,
)Properties
- readonly
namestring - readonly
kind"connectrpc" - readonly
statusMessagestring - readonly
metadataHeaders | null
#GrpcNetworkError
class GrpcNetworkError extends ClientErrorClientErrorError thrown when a network-level failure occurs.
This error indicates that the request could not be processed by the server due to network issues (connection refused, DNS resolution failure, timeout, etc.). Unlike ConnectRpcError, this error means the server was never reached.
Constructor
new GrpcNetworkError(message: string, options?: ErrorOptions)Properties
- readonly
namestring - readonly
kind"connectrpc"
Interfaces
#ErrorDetail
interface ErrorDetailRich error detail from google.rpc.Status.
ConnectRPC errors can include structured details encoded in error responses. These details follow the google.protobuf.Any format with a type URL and value.
Properties
- readonly
typeUrlstringType URL identifying the error detail type. Common types include:
- "type.googleapis.com/google.rpc.BadRequest"
- "type.googleapis.com/google.rpc.DebugInfo"
- "type.googleapis.com/google.rpc.RetryInfo"
- "type.googleapis.com/google.rpc.QuotaFailure"
- readonly
valueunknownDecoded error detail value. The structure depends on the typeUrl.
#GrpcClient
interface GrpcClient extends AsyncDisposableConnectRPC client interface.
Field Name Conventions
This client automatically handles field name conversion between protobuf and JavaScript:
- Request fields: Accept both
snake_case(protobuf style) andcamelCase(JavaScript style) - Response fields: Converted to JavaScript conventions based on response type:
response.data: Plain JSON object withcamelCasefield names (no$typeName)response.raw: Original protobuf Message object with all metadata (includes$typeName)
Examples
const client = createConnectRpcClient({ url: "http://localhost:50051" });
// Request: Both formats work
await client.call("echo.Echo", "echoWithDelay", {
message: "hello",
delayMs: 100, // camelCase (recommended)
// delay_ms: 100, // snake_case also works
});
// Response: data is JSON, raw is protobuf Message
const response = await client.call("echo.Echo", "echo", { message: "test" });
console.log(response.data); // { message: "test", metadata: {...} }
console.log(response.raw); // { $typeName: "echo.EchoResponse", message: "test", ... }
| Name | Description |
|---|---|
config | Client configuration |
reflection | Reflection API (only available when schema: "reflection") |
call() | Make a unary RPC call. |
serverStream() | Make a server streaming RPC call. |
clientStream() | Make a client streaming RPC call. |
bidiStream() | Make a bidirectional streaming RPC call. |
close() | Close the client connection. |
Properties
Client configuration
Reflection API (only available when schema: "reflection")
Methods
call<TRequest>(
serviceName: string,
methodName: string,
request: TRequest,
options?: ConnectRpcOptions,
): Promise<ConnectRpcResponse>Make a unary RPC call.
Parameters
serviceNamestring- Service name (e.g., "echo.EchoService")
methodNamestring- Method name (e.g., "echo")
requestTRequest- Request message
options?ConnectRpcOptions- Call options
serverStream<TRequest>(
serviceName: string,
methodName: string,
request: TRequest,
options?: ConnectRpcOptions,
): AsyncIterable<ConnectRpcResponse>Make a server streaming RPC call.
Parameters
serviceNamestring- Service name
methodNamestring- Method name
requestTRequest- Request message
options?ConnectRpcOptions- Call options
clientStream<TRequest>(
serviceName: string,
methodName: string,
requests: AsyncIterable<TRequest>,
options?: ConnectRpcOptions,
): Promise<ConnectRpcResponse>Make a client streaming RPC call.
Parameters
serviceNamestring- Service name
methodNamestring- Method name
requestsAsyncIterable<TRequest>- Async iterable of request messages
options?ConnectRpcOptions- Call options
bidiStream<TRequest>(
serviceName: string,
methodName: string,
requests: AsyncIterable<TRequest>,
options?: ConnectRpcOptions,
): AsyncIterable<ConnectRpcResponse>Make a bidirectional streaming RPC call.
Parameters
serviceNamestring- Service name
methodNamestring- Method name
requestsAsyncIterable<TRequest>- Async iterable of request messages
options?ConnectRpcOptions- Call options
close(): Promise<void>Close the client connection.
#GrpcClientConfig
interface GrpcClientConfig extends Omit<ConnectRpcClientConfig, "protocol">Configuration for creating a gRPC client.
This is a subset of ConnectRpcClientConfig with protocol fixed to "grpc".
#GrpcErrorOptions
interface GrpcErrorOptions extends ErrorOptionsOptions for ConnectRpcError construction.
| Name | Description |
|---|---|
metadata | Headers/metadata from the ConnectRPC response. |
details | Rich error details from google.rpc.Status. |
Properties
- readonly
metadata?Headers | nullHeaders/metadata from the ConnectRPC response.
Rich error details from google.rpc.Status.
#GrpcOptions
interface GrpcOptions extends CommonOptionsOptions for individual ConnectRPC calls.
| Name | Description |
|---|---|
metadata | Metadata to send with the request. |
throwOnError | Whether to throw ConnectRpcError on non-OK responses (code !== 0) or failures. |
Properties
- readonly
metadata?HeadersInitMetadata to send with the request.
- readonly
throwOnError?booleanWhether to throw ConnectRpcError on non-OK responses (code !== 0) or failures. Overrides ConnectRpcClientConfig.throwOnError.
#GrpcResponseError
interface GrpcResponseError<T = any> extends ConnectRpcResponseBase<T>ConnectRPC response with gRPC error (statusCode !== 0).
The server processed the request but returned an error status.
| Name | Description |
|---|---|
processed | — |
ok | — |
error | — |
statusCode | gRPC status code (1-16). |
statusMessage | Status message describing the error. |
headers | Response headers. |
trailers | Response trailers (sent at end of RPC). |
raw | Raw ConnectError. |
data | No data for error responses. |
Properties
- readonly
processedtrue - readonly
okfalse gRPC status code (1-16).
- readonly
statusMessagestringStatus message describing the error.
- readonly
headersHeadersResponse headers.
- readonly
trailersHeadersResponse trailers (sent at end of RPC).
- readonly
rawConnectErrorRaw ConnectError.
- readonly
datanullNo data for error responses.
#GrpcResponseFailure
interface GrpcResponseFailure<T = any> extends ConnectRpcResponseBase<T>Failed ConnectRPC request (network error, connection refused, etc.).
The request did not reach gRPC processing.
| Name | Description |
|---|---|
processed | — |
ok | — |
error | — |
statusCode | Status code (null for network failures). |
statusMessage | Status message (null for network failures). |
headers | Response headers (null for failures). |
trailers | Response trailers (null for failures). |
raw | No raw response (request didn't reach server). |
data | No data (request didn't reach server). |
Properties
- readonly
processedfalse - readonly
okfalse - readonly
statusCodenullStatus code (null for network failures).
- readonly
statusMessagenullStatus message (null for network failures).
- readonly
headersnullResponse headers (null for failures).
- readonly
trailersnullResponse trailers (null for failures).
- readonly
rawnullNo raw response (request didn't reach server).
- readonly
datanullNo data (request didn't reach server).
#GrpcResponseSuccess
interface GrpcResponseSuccess<T = any> extends ConnectRpcResponseBase<T>Successful ConnectRPC response (statusCode === 0).
| Name | Description |
|---|---|
processed | — |
ok | — |
error | — |
statusCode | gRPC status code (always 0 for success). |
statusMessage | Status message (null for successful responses). |
headers | Response headers. |
trailers | Response trailers (sent at end of RPC). |
raw | Raw protobuf Message object. |
data | Response data as plain JavaScript object (JSON representation). |
Properties
- readonly
processedtrue - readonly
oktrue - readonly
errornull - readonly
statusCode0gRPC status code (always 0 for success).
- readonly
statusMessagenullStatus message (null for successful responses).
- readonly
headersHeadersResponse headers.
- readonly
trailersHeadersResponse trailers (sent at end of RPC).
- readonly
rawunknownRaw protobuf Message object.
- readonly
dataT | nullResponse data as plain JavaScript object (JSON representation).
#MethodInfo
interface MethodInfoMethod information from reflection.
| Name | Description |
|---|---|
name | Method name (e.g., "Echo") |
localName | Local name (camelCase) |
kind | Method kind |
inputType | Input message type name |
outputType | Output message type name |
idempotent | Whether the method is idempotent |
Properties
- readonly
namestringMethod name (e.g., "Echo")
- readonly
localNamestringLocal name (camelCase)
- readonly
kind"unary" | "server_streaming" | "client_streaming" | "bidi_streaming"Method kind
- readonly
inputTypestringInput message type name
- readonly
outputTypestringOutput message type name
- readonly
idempotentbooleanWhether the method is idempotent
#ReflectionApi
interface ReflectionApiReflection API for ConnectRPC client. Only available when client is created with schema: "reflection".
| Name | Description |
|---|---|
enabled | Check if reflection is enabled. |
listServices() | List all available services on the server. |
getServiceInfo() | Get detailed information about a specific service. |
listMethods() | Get methods for a specific service. |
hasService() | Check if a service exists. |
Properties
- readonly
enabledbooleanCheck if reflection is enabled.
Methods
listServices(): Promise<ServiceInfo[]>List all available services on the server.
getServiceInfo(serviceName: string): Promise<ServiceDetail>Get detailed information about a specific service.
Parameters
serviceNamestring- Fully qualified service name (e.g., "echo.EchoService")
listMethods(serviceName: string): Promise<MethodInfo[]>Get methods for a specific service.
Parameters
serviceNamestring- Fully qualified service name
hasService(serviceName: string): Promise<boolean>Check if a service exists.
Parameters
serviceNamestring- Fully qualified service name
#ServiceDetail
interface ServiceDetailDetailed service information.
| Name | Description |
|---|---|
name | Service name |
fullName | Fully qualified service name |
packageName | Package name |
protoFile | Proto file name |
methods | All methods |
Properties
- readonly
namestringService name
- readonly
fullNamestringFully qualified service name
- readonly
packageNamestringPackage name
- readonly
protoFilestringProto file name
All methods
#ServiceInfo
interface ServiceInfoService information from reflection.
Properties
- readonly
namestringFully qualified service name (e.g., "echo.EchoService")
- readonly
filestringProto file name
#TlsConfig
interface TlsConfigTLS configuration for ConnectRPC connections.
| Name | Description |
|---|---|
rootCerts | Root CA certificate (PEM format). |
clientCert | Client certificate (PEM format). |
clientKey | Client private key (PEM format). |
insecure | Skip server certificate verification (use only for testing). |
Properties
- readonly
rootCerts?Uint8ArrayRoot CA certificate (PEM format).
- readonly
clientCert?Uint8ArrayClient certificate (PEM format).
- readonly
clientKey?Uint8ArrayClient private key (PEM format).
- readonly
insecure?booleanSkip server certificate verification (use only for testing).
Functions
#createGrpcClient
function createGrpcClient(config: GrpcClientConfig): ConnectRpcClientCreate a new gRPC client instance.
This is a thin wrapper around createConnectRpcClient with protocol: "grpc" fixed.
The client provides Server Reflection support for runtime service discovery.
Parameters
configGrpcClientConfig- Client configuration including server address
Returns
ConnectRpcClient — A new gRPC client instance
Examples
Basic usage with reflection
import { createGrpcClient } from "@probitas/client-grpc";
const client = createGrpcClient({
url: "http://localhost:50051",
});
// Call a method
const response = await client.call(
"echo.EchoService",
"echo",
{ message: "Hello!" }
);
console.log(response.data);
await client.close();
Service discovery with reflection
import { createGrpcClient } from "@probitas/client-grpc";
const client = createGrpcClient({
url: "http://localhost:50051",
});
// Discover available services
const services = await client.reflection.listServices();
console.log("Available services:", services);
// Get method information
const info = await client.reflection.getServiceInfo("echo.EchoService");
console.log("Methods:", info.methods);
await client.close();
Testing error responses
import { createGrpcClient } from "@probitas/client-grpc";
const client = createGrpcClient({ url: "http://localhost:50051" });
const response = await client.call(
"user.UserService",
"getUser",
{ id: "non-existent" },
{ throwOnError: false }
);
if (!response.ok) {
console.log("Error code:", response.statusCode); // NOT_FOUND = 5
}
await client.close();
Using await using for automatic cleanup
import { createGrpcClient } from "@probitas/client-grpc";
await using client = createGrpcClient({
url: "http://localhost:50051",
});
const res = await client.call("echo.EchoService", "echo", { message: "test" });
console.log(res.data);
// Client automatically closed when scope exits
#getGrpcStatusName
function getGrpcStatusName(code: ConnectRpcStatusCode): stringGet the name of a ConnectRPC/gRPC status code.
Parameters
Examples
getStatusName(0); // "OK"
getStatusName(5); // "NOT_FOUND"
getStatusName(16); // "UNAUTHENTICATED"
#isGrpcStatusCode
function isGrpcStatusCode(code: number): code is ConnectRpcStatusCodeCheck if a number is a valid ConnectRPC/gRPC status code.
Parameters
codenumber
Examples
isConnectRpcStatusCode(0); // true
isConnectRpcStatusCode(16); // true
isConnectRpcStatusCode(99); // false
Types
#FileDescriptorSet
type FileDescriptorSet = MessageShape<FileDescriptorSetSchema>FileDescriptorSet message type from @bufbuild/protobuf. This is the decoded protobuf message containing file descriptors.
#GrpcResponse
type GrpcResponse<T = any> = ConnectRpcResponseSuccess<T>
| ConnectRpcResponseError<T>
| ConnectRpcResponseFailure<T>ConnectRPC response union type.
Use processed to distinguish between server responses and failures:
processed === true: Server responded (Success or Error)processed === false: Request failed (Failure)
Use ok to check for success:
ok === true: Success (statusCode === 0)ok === false: Error or Failure
#GrpcStatusCode
type GrpcStatusCode = unknownConnectRPC/gRPC status code type. Derived from ConnectRpcStatus values.
Variables
#GrpcStatus
const GrpcStatus: {
OK: number;
CANCELLED: number;
UNKNOWN: number;
INVALID_ARGUMENT: number;
DEADLINE_EXCEEDED: number;
NOT_FOUND: number;
ALREADY_EXISTS: number;
PERMISSION_DENIED: number;
RESOURCE_EXHAUSTED: number;
FAILED_PRECONDITION: number;
ABORTED: number;
OUT_OF_RANGE: number;
UNIMPLEMENTED: number;
INTERNAL: number;
UNAVAILABLE: number;
DATA_LOSS: number;
UNAUTHENTICATED: number;
}ConnectRPC/gRPC status codes. These codes are used by both gRPC and ConnectRPC protocols.
