Nestjs interceptor for dto serialize. (snake -> camel to input dto, camel -> snake to returned json)
SerializeInterceptor
intercept request/response, and deserialize/serialize to dto data.
in short, json layer: snake
model layer: camel
It also works to nested object.
when client send below data,
{
"name": "nolleh",
"email": "[email protected]",
"some_snake_data": "hello world"
"live": {
"country": "South Korea",
"city": "Seongnam",
"some_snake_data": "hello world2"
}
}
you can retrieve as (in code)
class LiveDto {
country,
city,
someSnakeData
}
class MyDto {
name,
email,
someSnakeData,
live,
}
in your main code, put this.
you can check this code from
import { SerializeInterceptor } from 'serialize-interceptor';
import { NestFactory } from '@nestjs/core';
...
const app = await NestFactory.create(AppModule);
/** use our interceptor **/
app.useGlobalInterceptors(new SerializeInterceptor);
// @since 1.1.5
// if you want to customize serializer, then put your strategy.
// const strategy: Strategy = {
// in: DEFAULT_STRATEGY.in,
// out: (v) => {
// // return 'test-swallow up!';
// return snakeToCamel(v)
// },
// };
// app.useGlobalInterceptors(new SerializeInterceptor(strategy));
OR in module
@Module({
controllers: [AppController],
providers: [
{
provide: APP_INTERCEPTOR,
useClass: SerializeInterceptor,
},
/** @since 1.1.5
// if you want to customize serializer, then put your strategy.
{
provide: Strategy,
useFactory: () => ({
in: DEFAULT_STRATEGY.in,
out: (v) => {
// return 'test-swallow up!';
// your custom func. the default for 'out' is.. snakeToCamel.
return snakeToCamel(v);
},
}),
},
**/
})
export class AppModule {}
you can put your serialize strategy as you wish, that briefly shown in above snippet.
serializeInterceptor provides classes to help definition your own class.
/** because the regenerated value's field is differ from original,
* it is hard to declare return type.
* the input type is also not meaningful.
*
* in: request layer (default: snakeToCamel),
* out: response layer (default: camelToSnake).
*
* i.e. const DEFAULT_STRATEGY: Strategy = { in: snakeToCamel, out: camelToSnake };
*/
export class Strategy {
in: (value: any) => any;
out: (value: any) => any;
}
export const DEFAULT_STRATEGY: Strategy = {
in: snakeToCamel,
out: camelToSnake,
};
as you can see, implementing class Strategy
that contains in/out function,
and put it as constructor (by injecting or creating new one),
then the interceptor will work as you defined.
🤔 is there A strategy that one you want to be provided by this lib?
let me know!
for now :
Name | Desc | Remark (side effect) | Default |
---|---|---|---|
snakeToCamel | snake -> camel | dash(-, kebab) also converted to camel | default for in (request) |
camelToSnake | camel -> snake | starting with capital (pascal) also converted to snake | default for out (response) |
kebabToCamel | kebab -> camel | X | |
camelTokebab | camel -> kebab | X |
⚠️ the default snakeToCamel / camelToSnake has side effect that also converting kebab, pascal.
considering it’s usage, couldn’t simply say the side effect is disadvantage.
but to handle diversity of usage case, there will be soon added additional strategy that doesn’t have the effect.
nestjs
designed for nestjs interceptor.