Skip to Content
🎉 gRPCity 3.0 is released. Read more →

Metadata

Metadata is gRPC’s headers — key/value pairs that travel alongside requests and responses. You’ll reach for it for tracing, request provenance, auth tokens, and other cross-cutting fields that don’t belong in the message body.

Sending from the client

loader.makeMetadata() is the ergonomic path — it takes a plain object and returns a Metadata instance. If you prefer to build one yourself, gRPCity also re-exports the Metadata class so you don’t have to depend on @grpc/grpc-js directly:

import { Metadata } from 'grpcity' const meta = new Metadata() meta.set('x-tenant', 'acme')

The example below uses the helper:

const client = clients.get('test.helloworld.Greeter') const meta = loader.makeMetadata({ 'x-cache-control': 'max-age=100', 'x-business-id': ['grpcity', 'testing'], 'x-timestamp-client': 'begin=' + new Date().toISOString() }) const { status, metadata, response } = await client.sayGreet({ name: 'greeter' }, meta) console.log(metadata)

The trailing metadata looks like this:

Terminal
Metadata { internalRepr: Map(8) { 'content-type' => [ 'application/grpc+proto' ], 'x-cache-control' => [ 'max-age=100' ], 'x-business-id' => [ 'grpcity, testing' ], 'x-timestamp-client' => [ 'begin=2023-11-01T03:31:05.942Z' ], 'x-client-hostname' => [ 'ChakhsudeAir' ], 'user-agent' => [ 'grpc-node-js/1.9.7' ], 'x-timestamp-server' => [ 'received=2023-11-01T03:31:06.987Z' ], 'date' => [ 'Wed, 01 Nov 2023 03:31:06 GMT' ] }, options: {} }

The client defaults to sending the following metadata:

  • x-client-hostname: The value is the operating system’s hostname.

The server defaults to sending the following metadata:

  • content-type: The value is generally application/grpc+proto.
  • user-agent: The value is generally grpc-node-js/1.9.7.
  • date: The value is generally Wed, 01 Nov 2023 03:31:06 GMT.

Receiving on the server

Inside any handler, call.metadata is a fully populated Metadata instance. Clone it before mutating, then read values with get(key):

async sayGreet(call) { const { name } = call.request // Retrieve metadata information from the call const metadata = call.metadata.clone() // Get specific metadata key-value pairs const cacheAge = metadata.get('x-cache-control') const businessId = metadata.get('x-business-id') const clientTimestamp = metadata.get('x-timestamp-client') // Print metadata values console.log(cacheAge) console.log(businessId) console.log(clientTimestamp) return { message: `hello ${name || "world"} by Greeter in server1` } }

The output is as follows:

Terminal
[ 'max-age=100' ] [ 'grpcity, testing' ] [ 'begin=2023-10-31T16:34:22.296Z' ]

Sending from the server

To attach metadata to the response (visible to the client as trailing metadata), call sendMetadata() on the call:

async SayHello (call) { const metadata = call.metadata.clone() metadata.add('x-timestamp-server', 'received=' + new Date().toISOString()) call.sendMetadata(metadata) // Omitted... }

The client receives this metadata in the metadata field of the call result.

Last updated on