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:
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’shostname.
The server defaults to sending the following metadata:
content-type: The value is generallyapplication/grpc+proto.user-agent: The value is generallygrpc-node-js/1.9.7.date: The value is generallyWed, 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:
[ '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.