@nestjs/microservices
Version:
Nest - modern, fast, powerful node.js web framework (@microservices)
52 lines (51 loc) • 2.23 kB
JavaScript
import { MaxKafkaHeadersExceededException } from '../errors/max-kafka-headers-exceeded.exception.js';
import { isNil, isObject, isPlainObject, isString, isUndefined, } from '@nestjs/common/internal';
// kafkajs encodes each value of the headers (a repeated header has several)
// as a header of its own, at about 1 kB apiece
const MAX_HEADER_VALUES = 10_000;
/**
* @publicApi
*/
export class KafkaRequestSerializer {
serialize(value) {
const isNotKafkaMessage = isNil(value) ||
!isObject(value) ||
(!('key' in value) && !('value' in value));
// Serialize a copy, headers included: ClientKafka and ServerKafka write
// correlation metadata into the returned headers, and the caller's record
// may be frozen, reused or sent concurrently.
const record = (isNotKafkaMessage ? { value } : value);
// Spreading a string or an array (as an echo handler may return them)
// would turn each of its characters or items into a header
const headers = isObject(record.headers) && !Array.isArray(record.headers)
? record.headers
: {};
let headerValues = 0;
for (const headerValue of Object.values(headers)) {
headerValues += Array.isArray(headerValue) ? headerValue.length : 1;
}
if (headerValues > MAX_HEADER_VALUES) {
throw new MaxKafkaHeadersExceededException(headerValues, MAX_HEADER_VALUES);
}
const request = { ...record, headers: { ...headers } };
request.value = this.encode(request.value);
if (!isNil(request.key)) {
request.key = this.encode(request.key);
}
return request;
}
encode(value) {
const isObjectOrArray = !isNil(value) && !isString(value) && !Buffer.isBuffer(value);
if (isObjectOrArray) {
return isPlainObject(value) ||
Array.isArray(value) ||
value.toString == Object.prototype.toString // Prevent default [object Object] behavior
? JSON.stringify(value)
: value.toString();
}
else if (isUndefined(value)) {
return null;
}
return value;
}
}