dto-serializer
v0.1.1
Published
DTO serializer
Readme
DTO Serializer
Fast, minimal, type-safe, zero-dependency DTO serializer for Node
Get Started
Install the package
npm i dto-serializer
yarn dto-serializerTo create a DTO schema, simply declare an object with the properties you wish to expose:
const TestDto = {
foo: true,
bar: true
};Then, simply pass the data to be serialized to the serialize function along with the schema.
import { serialize } from 'dto-serializer';
const data = {
foo: 123,
bar: 'abc',
notExposed: 'abcd'
}
const serializedData = serialize(data, TestDto)Usage with NestJS
To use this package with NestJS, create an interceptor, pass it the schema and serialize the data in the intercept method.
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
import { map, Observable } from 'rxjs';
import { serialize, Schema } from 'dto-serializer';
export class SerializerInterceptor implements NestInterceptor {
constructor(private schema: Schema) {}
intercept(context: ExecutionContext, handler: CallHandler): Observable<any> {
return handler.handle().pipe(map((data: any) => serialize(data, this.schema)));
}
}Design Principles
- Purely declarative
- no need to write ugly maps or other functions
- Properties are hidden by default
- unless you specify a property in your DTO object, it will be omitted from the output. This ensures that, as your data changes, you won't unintentionally leak properties in the output.
- Type-safe
Usage
- Declare a DTO object:
const TestDto = {
foo: true,
bar: true
};- Import the
serializefunction and provide the data and the DTO:
const data = {
foo: 'abc',
bar: [12, 34]
};
serialize(data, TestDto)Features
- Expose properties
To expose a property, it suffices to set its value in the DTO object to true.
Conversely, to omit a property, don't add it in the DTO object, or set the value to false.
- Transformations
You can pass custom transformation functions to each property
const TestDto = {
foo: (value) => Number(value, 10),
bar: (value) => value.toUppercase()
};- Exposing in a different key
To expose a property in a different key, use the ":key" value where key is the name of the original key
const data = {
_id: '123'
}
// this will map the _id property of the data to id in the output
const UserDto = {
id: ':_id'
}- Multiple transformations
To apply multiple transformations to a property, combine them in an array. This is especially useful when a different field than the exposed one needs to be transformed:
const data = {
user: ' User Name '
}
// this will trim the user field and expose it as userName
const UserDto = {
userName: [':user', ( value ) => value.trim()]
}- Wildcards
Dealing with dynamically shaped objects is a huge pain point when working with libraries like class-transformer. Sometimes we only know the object values, but not the exact keys:
const features = {
someFeature: true,
otherFeature: false
}Other times, part the object we want to serialize is so dynamic that we simply want to return it as-is. Consider an endpoint which returns the responses of one or multiple API calls. Depending on the number of calls it could return short or long responses.
const data = {
status: 'OK',
}
const data1 = {
status: {status: 200, response: 'OK'},
}
const data2 = {
status: {statuses: [200, 404], responses: ['OK', 'NOT_FOUND']},
}For both of these cases, dto-serializer provides a handy feature called wildcards:
To serialize an object with dynamic key names, use the * symbol as a key:
const FeaturesDTO = {
'*': true
}To serialize a dynamic object, use the wildcard as a value.
// this will serialize all properties from the status key, whatever the value is:
const ResponseDTO = {
status: '*'
}Inheritance
To inherit a DTO class, simply merge it with another one as you would do with plain objects:
const TestDto = {
foo: true,
bar: true
};
const HideBarDto = {
...TestDto,
bar: false
}This will keep the foo property of TestDto, but hide the bar property.
