Metadata
Metadata 是 gRPC 的「header」——伴随请求/响应的一组键值对。链路追踪、调用来源、鉴权 token,以及其他不该塞进 message body 的横切字段,都靠它传递。
客户端发送
loader.makeMetadata() 是最顺手的方式——传一个普通对象,它返回一个 Metadata 实例。如果你想自己构造 Metadata,gRPCity 也把 Metadata 类从主包重新导出,免去对 @grpc/grpc-js 的直接依赖:
import { Metadata } from 'grpcity'
const meta = new Metadata()
meta.set('x-tenant', 'acme')下面用 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)返回的 trailing metadata 结构如下:
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: {}
}客户端默认发送以下的 metadata:
x-client-hostname: 值为操作系统的hostname;
服务端默认发送以下的 metadata:
content-type: 值一般为application/grpc+proto;user-agent: 值一般为grpc-node-js/1.9.7;date: 值一般为Wed, 01 Nov 2023 03:31:06 GMT;
服务端接收
任意 handler 中,call.metadata 都是一个完整的 Metadata 实例。修改前先 clone() 一下,再用 get(key) 读取:
async sayGreet(call) {
const { name } = call.request
// 获取 call 里的 metadata 信息
const metadata = call.metadata.clone()
// 获取具体的 metadata kv
const cacheAge = metadata.get('x-cache-control')
const businessId = metadata.get('x-business-id')
const clientTimestamp = metadata.get('x-timestamp-client')
// 打印 metadata value
console.log(cacheAge)
console.log(businessId)
console.log(clientTimestamp)
return {
message: `hello ${name || "world"} by Greeter in server1`
}
}输出如下:
Terminal
[ 'max-age=100' ]
[ 'grpcity, testing' ]
[ 'begin=2023-10-31T16:34:22.296Z' ]服务端发送
需要把 metadata 附加到响应(客户端会作为 trailing metadata 收到)时,在 call 上调 sendMetadata():
async SayHello (call) {
const metadata = call.metadata.clone()
metadata.add('x-timestamp-server', 'received=' + new Date().toISOString())
call.sendMetadata(metadata)
// 省略...
}客户端会在调用结果的 metadata 字段里收到这份信息。
Last updated on