or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

client-management.mderror-handling.mdindex.mdinterceptors.mdmethod-descriptors.mdstreaming.md
tile.json

method-descriptors.mddocs/

Method Descriptors and Requests

Method descriptors define gRPC method metadata including serialization functions, type information, and request/response handling for type-safe RPC operations.

Capabilities

MethodDescriptor

Core class that describes a gRPC method with its type information and serialization functions.

/**
 * Describes a gRPC method with its metadata and serialization functions
 */
class MethodDescriptor<REQ, RESP> {
  /**
   * Create a new method descriptor
   * @param name - The gRPC method name (e.g., '/package.Service/Method')
   * @param methodType - The method type (UNARY, SERVER_STREAMING, etc.)
   * @param requestType - Constructor for the request message type
   * @param responseType - Constructor for the response message type
   * @param requestSerializeFn - Function to serialize request messages
   * @param responseDeserializeFn - Function to deserialize response messages
   */
  constructor(
    name: string,
    methodType: string,
    requestType: new (...args: unknown[]) => REQ,
    responseType: new (...args: unknown[]) => RESP,
    requestSerializeFn: any,
    responseDeserializeFn: any
  );

  /**
   * Get the method name
   * @returns The gRPC method name
   */
  getName(): string;

  /**
   * Get the method type
   * @returns The method type string
   */
  getMethodType(): string;

  /**
   * Get the response message constructor
   * @returns Constructor function for response messages
   */
  getResponseMessageCtor(): new (...args: unknown[]) => RESP;

  /**
   * Get the request message constructor
   * @returns Constructor function for request messages
   */
  getRequestMessageCtor(): new (...args: unknown[]) => REQ;

  /**
   * Get the response deserialization function
   * @returns Function to deserialize response bytes to message objects
   */
  getResponseDeserializeFn(): (bytes: any) => RESP;

  /**
   * Get the request serialization function
   * @returns Function to serialize request messages to bytes
   */
  getRequestSerializeFn(): (message: REQ) => any;

  /**
   * Create a request object for this method
   * @param requestMessage - The request message instance
   * @param metadata - Optional request metadata
   * @param callOptions - Optional call options
   * @returns Request object for RPC calls
   */
  createRequest(
    requestMessage: REQ,
    metadata?: Metadata,
    callOptions?: CallOptions
  ): Request<REQ, RESP>;

  /**
   * Create a unary response object
   * @param responseMessage - The response message instance
   * @param metadata - Optional response metadata
   * @param status - Optional gRPC status
   * @returns UnaryResponse object
   */
  createUnaryResponse(
    responseMessage: RESP,
    metadata?: Metadata,
    status?: Status
  ): UnaryResponse<REQ, RESP>;
}

Request Interface

Represents an individual gRPC request with message, metadata, and call options.

/**
 * Represents an individual gRPC request instance
 */
interface Request<REQ, RESP> {
  /**
   * Get the request message
   * @returns The request message instance
   */
  getRequestMessage(): REQ;

  /**
   * Get the method descriptor for this request
   * @returns The method descriptor
   */
  getMethodDescriptor(): MethodDescriptor<REQ, RESP>;

  /**
   * Get the request metadata
   * @returns The metadata object
   */
  getMetadata(): Metadata;

  /**
   * Get the call options
   * @returns The call options or undefined
   */
  getCallOptions(): CallOptions | undefined;

  /**
   * Add metadata to the request
   * @param key - Metadata key
   * @param value - Metadata value
   * @returns New request instance with added metadata
   */
  withMetadata(key: string, value: string): Request<REQ, RESP>;

  /**
   * Add a gRPC call option
   * @param name - Option name
   * @param value - Option value
   * @returns New request instance with added option
   */
  withGrpcCallOption<VALUE>(name: string, value: VALUE): Request<REQ, RESP>;
}

UnaryResponse Interface

Response object for unary RPC calls containing the response message, metadata, and status.

/**
 * Response object for unary RPC calls
 */
interface UnaryResponse<REQ, RESP> {
  /**
   * Get the response message
   * @returns The response message instance
   */
  getResponseMessage(): RESP;

  /**
   * Get the response metadata
   * @returns The metadata object
   */
  getMetadata(): Metadata;

  /**
   * Get the method descriptor
   * @returns The method descriptor
   */
  getMethodDescriptor(): MethodDescriptor<REQ, RESP>;

  /**
   * Get the gRPC status
   * @returns The status object or null
   */
  getStatus(): Status | null;
}

CallOptions

Runtime options for RPC calls with flexible key-value storage.

/**
 * Runtime options for RPC calls
 */
class CallOptions {
  /**
   * Create new call options
   * @param options - Initial options object
   */
  constructor(options?: { [key: string]: any });

  /**
   * Add or override a call option
   * @param name - Option name
   * @param value - Option value
   */
  setOption(name: string, value: any): void;

  /**
   * Get a call option value
   * @param name - Option name
   * @returns Option value or undefined
   */
  get(name: string): any;

  /**
   * Remove a call option
   * @param name - Option name to remove
   */
  removeOption(name: string): void;

  /**
   * Get all option keys
   * @returns Array of option keys
   */
  getKeys(): string[];
}

Method Types

Constants defining the available gRPC method types.

/**
 * gRPC Method Types
 */
namespace MethodType {
  /** Unary request and unary response */
  const UNARY: string;
  /** Unary request and streaming responses */
  const SERVER_STREAMING: string;
}

Usage Examples:

import { 
  MethodDescriptor, 
  MethodType, 
  CallOptions 
} from "grpc-web";

// Create a method descriptor for a unary call
const getProductMethod = new MethodDescriptor(
  '/ecommerce.ProductService/GetProduct',
  MethodType.UNARY,
  GetProductRequest,
  GetProductResponse,
  (req) => req.serializeBinary(),
  (bytes) => GetProductResponse.deserializeBinary(bytes)
);

// Create a method descriptor for server streaming
const listProductsMethod = new MethodDescriptor(
  '/ecommerce.ProductService/ListProducts',
  MethodType.SERVER_STREAMING,
  ListProductsRequest,
  ListProductsResponse,
  (req) => req.serializeBinary(),
  (bytes) => ListProductsResponse.deserializeBinary(bytes)
);

// Create a request with metadata
const request = getProductMethod.createRequest(
  new GetProductRequest().setId('123'),
  { 'authorization': 'Bearer token123' }
);

// Add more metadata
const requestWithAuth = request.withMetadata('x-api-key', 'key456');

// Working with call options
const callOptions = new CallOptions({
  timeout: 5000,
  retries: 3
});

callOptions.setOption('priority', 'high');
console.log(callOptions.get('timeout')); // 5000
console.log(callOptions.getKeys()); // ['timeout', 'retries', 'priority']

// Create request with call options
const requestWithOptions = getProductMethod.createRequest(
  new GetProductRequest().setId('123'),
  {},
  callOptions
);

// Process unary response
client.unaryCall(url, requestMsg, metadata, getProductMethod)
  .then(response => {
    console.log('Product:', response);
  })
  .catch(error => {
    console.error('Error:', error);
  });

Serialization Functions

Method descriptors require serialization and deserialization functions to convert between JavaScript objects and the wire format (typically Protocol Buffers):

  • Request Serialization: Converts request message objects to bytes for transmission
  • Response Deserialization: Converts received bytes back to response message objects

These functions are typically generated by the Protocol Buffer compiler (protoc) but can also be custom implementations for other serialization formats.

Method Naming Convention

gRPC method names follow the pattern: '/package.Service/Method'

  • package: The protobuf package name
  • Service: The gRPC service name
  • Method: The individual method name

For example: '/ecommerce.v1.ProductService/GetProduct'

Type Safety

Method descriptors provide full type safety through TypeScript generics:

  • REQ: The request message type
  • RESP: The response message type

This ensures that request messages, response messages, and serialization functions all have compatible types, preventing runtime type errors.