Configuring Custom Types
Schemas can contain types that cannot be represented by Javascript primitive types, or
where there's more than one possible type to deserialize into. For example,
the Avro logical type timestamp-millis
represents a date, but is serialized as a long
.
In order to deserialize that into a Date
object, we need to configure the schema library.
Avro
@kafkajs/confluent-schema-registry
uses the avsc
library for Avro encoding/decoding. The Schema Type Options
for Avro are passed to avsc.Type.forSchema
,
which allows us to set up a mapping between the logical type and the type we want to deserialize
into:
import { SchemaRegistry, SchemaType } from '@kafkajs/confluent-schema-registry'
import avro from 'avsc'
class DateType extends avro.types.LogicalType {
_fromValue(val: string) {
return new Date(val);
}
_toValue(date: Date): number {
return +date
}
_resolve(type: any) {
if (avro.Type.isType(type, 'long', 'string', 'logical:timestamp-millis')) {
return this._fromValue;
}
}
}
const options = {
[SchemaType.AVRO]: {
logicalTypes: { 'timestamp-millis': DateType }
}
}
const registry = new SchemaRegistry({ host: 'http://localhost:9092' }, options)
Custom long type
JavaScript represents all numbers as doubles internally, which means that it is possible
to lose precision when using very large numbers. In order to use a type that can
accomodate such large numbers, you can use the same configuration option as above to
have avsc use for example BigInt
or longjs
instead of the native number
type.
See Custom Long Types for more details.