@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 AsyncDisposable for 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
PackageDescription
`@probitas/client`Core utilities and types
`@probitas/client-grpc`gRPC client (wrapper with protocol: "grpc")

Installation

deno add jsr:@probitas/client-connectrpc

Classes

class

#ConnectRpcError

class ConnectRpcError extends ClientError

Error class for ConnectRPC/gRPC errors.

Use statusCode to distinguish between different gRPC error codes.

NameDescription
name
kind
statusCode
statusMessage
metadata
details
Constructor
new ConnectRpcError(
  message: string,
  statusCode: ConnectRpcStatusCode,
  statusMessage: string,
  options?: ConnectRpcErrorOptions,
)
Properties
  • readonlynamestring
  • readonlykind"connectrpc"
  • readonlystatusCodeConnectRpcStatusCode
  • readonlystatusMessagestring
  • readonlymetadataHeaders | null
  • readonlydetailsreadonly ErrorDetail[]
class

#ConnectRpcNetworkError

class ConnectRpcNetworkError extends ClientError

Error 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.

NameDescription
name
kind
Constructor
new ConnectRpcNetworkError(message: string, options?: ErrorOptions)
Properties
  • readonlynamestring
  • readonlykind"connectrpc"

Interfaces

interface

#ConnectRpcClient

interface ConnectRpcClient extends AsyncDisposable

ConnectRPC client interface.

Field Name Conventions

This client automatically handles field name conversion between protobuf and JavaScript:

  • Request fields: Accept both snake_case (protobuf style) and camelCase (JavaScript style)
  • Response fields: Converted to JavaScript conventions based on response type:
    • response.data: Plain JSON object with camelCase field 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", ... }
NameDescription
configClient configuration
reflectionReflection 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
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
    • 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
    • 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
    • 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
    • Call options
close(): Promise<void>

Close the client connection.

interface

#ConnectRpcClientConfig

interface ConnectRpcClientConfig extends CommonOptions

Configuration for creating a ConnectRPC client.

NameDescription
urlServer URL for ConnectRPC connections.
protocolProtocol to use.
httpVersionHTTP version to use.
tlsTLS configuration.
metadataDefault metadata to send with every request.
schemaSchema resolution configuration.
useBinaryFormatWhether to use binary format for messages.
throwOnErrorWhether to throw ConnectRpcError on non-OK responses (code !== 0) or failures.
Properties
  • readonlyurlstring | ConnectRpcConnectionConfig

    Server URL for ConnectRPC connections.

    Can be a URL string or a connection configuration object.

  • readonlyprotocol?ConnectProtocol

    Protocol to use.

  • readonlyhttpVersion?HttpVersion

    HTTP version to use.

  • readonlytls?TlsConfig

    TLS configuration. If not provided, uses insecure credentials.

  • readonlymetadata?HeadersInit

    Default metadata to send with every request.

  • readonlyschema?"reflection" | string | Uint8Array | FileDescriptorSet

    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
  • readonlyuseBinaryFormat?boolean

    Whether to use binary format for messages.

  • readonlythrowOnError?boolean

    Whether to throw ConnectRpcError on non-OK responses (code !== 0) or failures. Can be overridden per-request via ConnectRpcOptions.throwOnError.

interface

#ConnectRpcConnectionConfig

interface ConnectRpcConnectionConfig extends CommonConnectionConfig

ConnectRPC connection configuration.

Extends CommonConnectionConfig with ConnectRPC-specific options.

NameDescription
protocolProtocol to use.
pathService path prefix.
Properties
  • readonlyprotocol?"http" | "https"

    Protocol to use.

  • readonlypath?string

    Service path prefix.

interface

#ConnectRpcErrorOptions

interface ConnectRpcErrorOptions extends ErrorOptions

Options for ConnectRpcError construction.

NameDescription
metadataHeaders/metadata from the ConnectRPC response.
detailsRich error details from google.rpc.Status.
Properties
  • readonlymetadata?Headers | null

    Headers/metadata from the ConnectRPC response.

  • readonlydetails?readonly ErrorDetail[] | null

    Rich error details from google.rpc.Status.

interface

#ConnectRpcOptions

interface ConnectRpcOptions extends CommonOptions

Options for individual ConnectRPC calls.

NameDescription
metadataMetadata to send with the request.
throwOnErrorWhether to throw ConnectRpcError on non-OK responses (code !== 0) or failures.
Properties
  • readonlymetadata?HeadersInit

    Metadata to send with the request.

  • readonlythrowOnError?boolean

    Whether to throw ConnectRpcError on non-OK responses (code !== 0) or failures. Overrides ConnectRpcClientConfig.throwOnError.

interface

#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.

NameDescription
processed
ok
error
statusCodegRPC status code (1-16).
statusMessageStatus message describing the error.
headersResponse headers.
trailersResponse trailers (sent at end of RPC).
rawRaw ConnectError.
dataNo data for error responses.
Properties
  • readonlyprocessedtrue
  • readonlyokfalse
  • readonlyerrorConnectRpcError
  • readonlystatusCodeConnectRpcStatusCode

    gRPC status code (1-16).

  • readonlystatusMessagestring

    Status message describing the error.

  • readonlyheadersHeaders

    Response headers.

  • readonlytrailersHeaders

    Response trailers (sent at end of RPC).

  • readonlyrawConnectError

    Raw ConnectError.

  • readonlydatanull

    No data for error responses.

interface

#ConnectRpcResponseErrorParams

interface ConnectRpcResponseErrorParams

Parameters for creating an error ConnectRpcResponse.

NameDescription
error
rpcError
headers
trailers
duration
Properties
  • readonlyerrorConnectError
  • readonlyrpcErrorConnectRpcError
  • readonlyheadersHeaders
  • readonlytrailersHeaders
  • readonlydurationnumber
interface

#ConnectRpcResponseFailure

interface ConnectRpcResponseFailure<T = any> extends ConnectRpcResponseBase<T>

Failed ConnectRPC request (network error, connection refused, etc.).

The request did not reach gRPC processing.

NameDescription
processed
ok
error
statusCodeStatus code (null for network failures).
statusMessageStatus message (null for network failures).
headersResponse headers (null for failures).
trailersResponse trailers (null for failures).
rawNo raw response (request didn't reach server).
dataNo data (request didn't reach server).
Properties
  • readonlyprocessedfalse
  • readonlyokfalse
  • readonlystatusCodenull

    Status code (null for network failures).

  • readonlystatusMessagenull

    Status message (null for network failures).

  • readonlyheadersnull

    Response headers (null for failures).

  • readonlytrailersnull

    Response trailers (null for failures).

  • readonlyrawnull

    No raw response (request didn't reach server).

  • readonlydatanull

    No data (request didn't reach server).

interface

#ConnectRpcResponseFailureParams

interface ConnectRpcResponseFailureParams

Parameters for creating a failure ConnectRpcResponse.

NameDescription
error
duration
Properties
interface

#ConnectRpcResponseSuccess

interface ConnectRpcResponseSuccess<T = any> extends ConnectRpcResponseBase<T>

Successful ConnectRPC response (statusCode === 0).

NameDescription
processed
ok
error
statusCodegRPC status code (always 0 for success).
statusMessageStatus message (null for successful responses).
headersResponse headers.
trailersResponse trailers (sent at end of RPC).
rawRaw protobuf Message object.
dataResponse data as plain JavaScript object (JSON representation).
Properties
  • readonlyprocessedtrue
  • readonlyoktrue
  • readonlyerrornull
  • readonlystatusCode0

    gRPC status code (always 0 for success).

  • readonlystatusMessagenull

    Status message (null for successful responses).

  • readonlyheadersHeaders

    Response headers.

  • readonlytrailersHeaders

    Response trailers (sent at end of RPC).

  • readonlyrawunknown

    Raw protobuf Message object.

  • readonlydataT | null

    Response data as plain JavaScript object (JSON representation).

interface

#ConnectRpcResponseSuccessParams

interface ConnectRpcResponseSuccessParams<T = any>

Parameters for creating a successful ConnectRpcResponse.

NameDescription
response
schema
headers
trailers
duration
Properties
  • readonlyresponseT | null
  • readonlyschemaDescMessage | null
  • readonlyheadersHeaders
  • readonlytrailersHeaders
  • readonlydurationnumber
interface

#ErrorDetail

interface ErrorDetail

Rich 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.

NameDescription
typeUrlType URL identifying the error detail type.
valueDecoded error detail value.
Properties
  • readonlytypeUrlstring

    Type 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"
  • readonlyvalueunknown

    Decoded error detail value. The structure depends on the typeUrl.

interface

#MethodInfo

interface MethodInfo

Method information from reflection.

NameDescription
nameMethod name (e.g., "Echo")
localNameLocal name (camelCase)
kindMethod kind
inputTypeInput message type name
outputTypeOutput message type name
idempotentWhether the method is idempotent
Properties
  • readonlynamestring

    Method name (e.g., "Echo")

  • readonlylocalNamestring

    Local name (camelCase)

  • readonlykind"unary" | "server_streaming" | "client_streaming" | "bidi_streaming"

    Method kind

  • readonlyinputTypestring

    Input message type name

  • readonlyoutputTypestring

    Output message type name

  • readonlyidempotentboolean

    Whether the method is idempotent

interface

#ReflectionApi

interface ReflectionApi

Reflection API for ConnectRPC client. Only available when client is created with schema: "reflection".

NameDescription
enabledCheck 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
  • readonlyenabledboolean

    Check 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
interface

#ServiceDetail

interface ServiceDetail

Detailed service information.

NameDescription
nameService name
fullNameFully qualified service name
packageNamePackage name
protoFileProto file name
methodsAll methods
Properties
  • readonlynamestring

    Service name

  • readonlyfullNamestring

    Fully qualified service name

  • readonlypackageNamestring

    Package name

  • readonlyprotoFilestring

    Proto file name

  • readonlymethodsreadonly MethodInfo[]

    All methods

interface

#ServiceInfo

interface ServiceInfo

Service information from reflection.

NameDescription
nameFully qualified service name (e.g., "echo.EchoService")
fileProto file name
Properties
  • readonlynamestring

    Fully qualified service name (e.g., "echo.EchoService")

  • readonlyfilestring

    Proto file name

interface

#TlsConfig

interface TlsConfig

TLS configuration for ConnectRPC connections.

NameDescription
rootCertsRoot CA certificate (PEM format).
clientCertClient certificate (PEM format).
clientKeyClient private key (PEM format).
insecureSkip server certificate verification (use only for testing).
Properties
  • readonlyrootCerts?Uint8Array

    Root CA certificate (PEM format).

  • readonlyclientCert?Uint8Array

    Client certificate (PEM format).

  • readonlyclientKey?Uint8Array

    Client private key (PEM format).

  • readonlyinsecure?boolean

    Skip server certificate verification (use only for testing).

Functions

function

#createConnectRpcClient

function createConnectRpcClient(
  config: ConnectRpcClientConfig,
): ConnectRpcClient

Create 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
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
function

#fromConnectError

function fromConnectError(
  error: ConnectError,
  metadata?: Headers,
): ConnectRpcError

Convert 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

function

#getStatusName

function getStatusName(code: ConnectRpcStatusCode): string

Get the name of a ConnectRPC/gRPC status code.

Parameters
Examples
getStatusName(0);  // "OK"
getStatusName(5);  // "NOT_FOUND"
getStatusName(16); // "UNAUTHENTICATED"
function

#isConnectRpcStatusCode

function isConnectRpcStatusCode(code: number): code is ConnectRpcStatusCode

Check if a number is a valid ConnectRPC/gRPC status code.

Parameters
  • codenumber
Examples
isConnectRpcStatusCode(0);   // true
isConnectRpcStatusCode(16);  // true
isConnectRpcStatusCode(99);  // false

Types

type

#ConnectProtocol

type ConnectProtocol = "connect" | "grpc" | "grpc-web"

Protocol to use for ConnectRPC transport.

type

#ConnectRpcErrorType

type ConnectRpcErrorType = ConnectRpcError | ConnectRpcNetworkError

ConnectRPC error type union.

Contains either:

  • ConnectRpcError: gRPC error returned by the server
  • ConnectRpcNetworkError: Network-level failure before reaching the server
type

#ConnectRpcFailureError

type ConnectRpcFailureError = ConnectRpcNetworkError | AbortError | TimeoutError

Error types that indicate the operation was not processed. These are errors that occur before the request reaches the server.

type

#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
type

#ConnectRpcStatusCode

type ConnectRpcStatusCode = unknown

ConnectRPC/gRPC status code type. Derived from ConnectRpcStatus values.

type

#FileDescriptorSet

type FileDescriptorSet = MessageShape<FileDescriptorSetSchema>

FileDescriptorSet message type from @bufbuild/protobuf. This is the decoded protobuf message containing file descriptors.

type

#HttpVersion

type HttpVersion = "1.1" | "2"

HTTP version for transport.

Variables

const

#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.

Search Documentation