I have been using the Java Spring framework for developing Microservices. Recently I started exploring NestJS and have a question regarding building response DTOs.
In Spring, The controllers are lightweight, they hand over the call to Service Layer.
The service layer implements the business logic, and finally, they call the Mapper classes that are responsible for building the response DTOs. The mapper class might be as simple as cloning the entity to a DTO or might also build complex objects using multiple DB entity objects.
In NestJS, in most of the examples class-transformer
is being used. But I am not sure the class-transformer
is good enough for building complex objects. For me class-transformer
is basically cloning the object. The equivalent for which in Spring is
BeanUtils.copyProperties(workingWellCompositeMemberContactTrace, workingWellDailyMemberAggEntity);
So my question is in NestJS, what layer is responsible for building complex response objects? And Is sending Entity object to Controller a good practice?
CodePudding user response:
Someone in another answer draw this picture which explains the life cycle of a request inside NestJS (shout out to that person):
To answer your question: what layer is responsible for building complex response objects?
well I say that the interceptors are the last bit of logic that handles the requests, but what I guess you are asking is "where do entities convert automatically to DTOs?" which would explain your second question: Is sending Entity object to Controller a good practice?
Short answer: It depends. Long answer: DTOs are really useful to disattach your request logic with your service logic, there are some values you may not want the user to ever know and just populate them inside your logic... And so, it is a good practice to use them. But really, think of your project, the size of it and what you are trying to accomplish, specially now that you have to handle that conversion.
That said, onto the conversion between Entities and DTOs. One thing you could do is a total manual set between parameters:
export class UserDTO {
id: string;
name: string;
surname: string;
toEntity(dto:UserDTO) {
const model = new User();
model.id = id;
model.fullname = `${dto.name}, ${dto.surname}`
return model;
}
fromEntity(entity:User) {
const dto = new UserDTO();
dto.id = entity.id;
const [ name, surname ] = entity.(fullname as string).split(', ').map((name) => {name.tirm()});
dto.name = name,
dto.surname = surname;
}
}
On other hand, lots can be accomplished by class-transformer
and its use of instanceToPlain
and plainToClass
. With the use of decorators as Expose
and Exclude
you can handle most use cases.
And if that is not enough, you could use something like: https://www.npmjs.com/package/@automapper/nestjs