@probitas/client-connectrpc
ConnectRPC client for Probitas scenario testing framework.
This package provides a ConnectRPC-based client with Server Reflection support, designed for integration testing of gRPC and Connect protocol services.
Features
- Protocol Support: Connect, gRPC, and gRPC-Web protocols
- Server Reflection: Auto-discover services and methods at runtime
- 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-connectrpc
Quick Start
import { createConnectRpcClient } from "@probitas/client-connectrpc";
// Create client (uses reflection by default)
const client = createConnectRpcClient({
url: "http://localhost:50051",
});
// Discover services via reflection
const services = await client.reflection.listServices();
console.log("Available services:", services);
// Get service info
const info = await client.reflection.getServiceInfo("echo.EchoService");
console.log("Methods:", info.methods);
// Call a method
const response = await client.call(
"echo.EchoService",
"echo",
{ message: "Hello!" }
);
console.log(response.data);
await client.close();
Testing Error Responses
import { createConnectRpcClient } from "@probitas/client-connectrpc";
const client = createConnectRpcClient({ url: "http://localhost:50051" });
// Test error responses without throwing
const errorResponse = await client.call(
"echo.EchoService",
"echo",
{ invalid: true },
{ throwOnError: false }
);
if (!errorResponse.ok) {
console.log("Error code:", errorResponse.statusCode); // INVALID_ARGUMENT = 3
}
await client.close();
Using with using Statement
import { createConnectRpcClient } from "@probitas/client-connectrpc";
await using client = createConnectRpcClient({ 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-grpc` | gRPC client (wrapper with protocol: "grpc") |
Links
Installation
deno add jsr:@probitas/client-connectrpcClasses
#ConnectRpcError
class ConnectRpcError 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 ConnectRpcError(
message: string,
statusCode: ConnectRpcStatusCode,
statusMessage: string,
options?: ConnectRpcErrorOptions,
)Properties
- readonly
namestring - readonly
kind"connectrpc" - readonly
statusMessagestring - readonly
metadataHeaders | null
#ConnectRpcNetworkError
class ConnectRpcNetworkError 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 ConnectRpcNetworkError(message: string, options?: ErrorOptions)Properties
- readonly
namestring - readonly
kind"connectrpc"
Interfaces
#ConnectRpcClient
interface ConnectRpcClient 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.
#ConnectRpcClientConfig
interface ConnectRpcClientConfig extends CommonOptionsConfiguration for creating a ConnectRPC client.
| Name | Description |
|---|---|
url | Server URL for ConnectRPC connections. |
protocol | Protocol to use. |
httpVersion | HTTP version to use. |
tls | TLS configuration. |
metadata | Default metadata to send with every request. |
schema | Schema resolution configuration. |
useBinaryFormat | Whether to use binary format for messages. |
throwOnError | Whether to throw ConnectRpcError on non-OK responses (code !== 0) or failures. |
Properties
Server URL for ConnectRPC connections.
Can be a URL string or a connection configuration object.
Protocol to use.
HTTP version to use.
TLS configuration. If not provided, uses insecure credentials.
- readonly
metadata?HeadersInitDefault metadata to send with every request.
Schema resolution configuration.
- "reflection": Use Server Reflection to discover services dynamically (default)
- string: Path to FileDescriptorSet binary file (from
buf build --output set.binpb) - Uint8Array: FileDescriptorSet binary data
- FileDescriptorSet: Pre-parsed FileDescriptorSet message object
- readonly
useBinaryFormat?booleanWhether to use binary format for messages.
- readonly
throwOnError?booleanWhether to throw ConnectRpcError on non-OK responses (code !== 0) or failures. Can be overridden per-request via ConnectRpcOptions.throwOnError.
#ConnectRpcConnectionConfig
interface ConnectRpcConnectionConfig extends CommonConnectionConfigConnectRPC connection configuration.
Extends CommonConnectionConfig with ConnectRPC-specific options.
Properties
- readonly
protocol?"http" | "https"Protocol to use.
- readonly
path?stringService path prefix.
#ConnectRpcErrorOptions
interface ConnectRpcErrorOptions 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.
#ConnectRpcOptions
interface ConnectRpcOptions 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.
#ConnectRpcResponseError
interface ConnectRpcResponseError<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.
#ConnectRpcResponseErrorParams
interface ConnectRpcResponseErrorParamsParameters for creating an error ConnectRpcResponse.
Properties
- readonly
errorConnectError - readonly
headersHeaders - readonly
trailersHeaders - readonly
durationnumber
#ConnectRpcResponseFailure
interface ConnectRpcResponseFailure<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).
#ConnectRpcResponseFailureParams
interface ConnectRpcResponseFailureParamsParameters for creating a failure ConnectRpcResponse.
Properties
- readonly
durationnumber
#ConnectRpcResponseSuccess
interface ConnectRpcResponseSuccess<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).
#ConnectRpcResponseSuccessParams
interface ConnectRpcResponseSuccessParams<T = any>Parameters for creating a successful ConnectRpcResponse.
Properties
- readonly
responseT | null - readonly
schemaDescMessage | null - readonly
headersHeaders - readonly
trailersHeaders - readonly
durationnumber
#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.
#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
#createConnectRpcClient
function createConnectRpcClient(
config: ConnectRpcClientConfig,
): ConnectRpcClientCreate a new ConnectRPC client instance.
The client supports multiple protocols (Connect, gRPC, gRPC-Web) and provides Server Reflection for runtime service discovery without compile-time code generation.
Parameters
configConnectRpcClientConfig- Client configuration including server URL and protocol options
Returns
ConnectRpcClient — A new ConnectRPC client instance
Examples
Basic usage with reflection
import { createConnectRpcClient } from "@probitas/client-connectrpc";
const client = createConnectRpcClient({
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 { createConnectRpcClient } from "@probitas/client-connectrpc";
const client = createConnectRpcClient({
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();
Using different protocols
import { createConnectRpcClient } from "@probitas/client-connectrpc";
// Connect protocol (HTTP/1.1 or HTTP/2)
const connectClient = createConnectRpcClient({
url: "http://localhost:8080",
protocol: "connect",
});
// gRPC protocol (HTTP/2 with binary protobuf)
const grpcClient = createConnectRpcClient({
url: "http://localhost:50051",
protocol: "grpc",
});
// gRPC-Web protocol (for browser compatibility)
const grpcWebClient = createConnectRpcClient({
url: "http://localhost:8080",
protocol: "grpc-web",
});
await connectClient.close();
await grpcClient.close();
await grpcWebClient.close();
Using connection config object
import { createConnectRpcClient } from "@probitas/client-connectrpc";
const client = createConnectRpcClient({
url: {
host: "grpc.example.com",
port: 443,
protocol: "https",
},
});
await client.close();
Using await using for automatic cleanup
import { createConnectRpcClient } from "@probitas/client-connectrpc";
await using client = createConnectRpcClient({
url: "http://localhost:50051",
});
const res = await client.call("echo.EchoService", "echo", { message: "test" });
// Client automatically closed when scope exits
#fromConnectError
function fromConnectError(
error: ConnectError,
metadata?: Headers,
): ConnectRpcErrorConvert ConnectRPC's ConnectError to ConnectRpcError.
Parameters
errorConnectError- The ConnectError from @connectrpc/connect
metadata?Headers- Optional metadata from the response
Returns
ConnectRpcError — ConnectRpcError with statusCode for discrimination
#getStatusName
function getStatusName(code: ConnectRpcStatusCode): stringGet the name of a ConnectRPC/gRPC status code.
Parameters
Examples
getStatusName(0); // "OK"
getStatusName(5); // "NOT_FOUND"
getStatusName(16); // "UNAUTHENTICATED"
#isConnectRpcStatusCode
function isConnectRpcStatusCode(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
#ConnectProtocol
type ConnectProtocol = "connect" | "grpc" | "grpc-web"Protocol to use for ConnectRPC transport.
#ConnectRpcErrorType
type ConnectRpcErrorType = ConnectRpcError | ConnectRpcNetworkErrorConnectRPC error type union.
Contains either:
- ConnectRpcError: gRPC error returned by the server
- ConnectRpcNetworkError: Network-level failure before reaching the server
#ConnectRpcFailureError
type ConnectRpcFailureError = ConnectRpcNetworkError | AbortError | TimeoutErrorError types that indicate the operation was not processed. These are errors that occur before the request reaches the server.
#ConnectRpcResponse
type ConnectRpcResponse<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
#ConnectRpcStatusCode
type ConnectRpcStatusCode = unknownConnectRPC/gRPC status code type. Derived from ConnectRpcStatus values.
#FileDescriptorSet
type FileDescriptorSet = MessageShape<FileDescriptorSetSchema>FileDescriptorSet message type from @bufbuild/protobuf. This is the decoded protobuf message containing file descriptors.
Variables
#ConnectRpcStatus
const ConnectRpcStatus: {
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.
