Search code examples
.netasp.net-web-apidto

DTO to domain model conversion strategies


I'm currently developing a restful API in .NET Web API, and have a domain model (using Entity Framework) and a DTO model to send to clients.

Obviously, there's some mapping that occurs between the domain model and the DTO model in the API.

One of my controllers in the API is an Employee controller, to which you can perform all the CRUD operations. I have created an EmployeeDto object to use with the controller - as an example, it might look like this:

public class EmployeeDto
{
   public Guid Id { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
}

And my controller might have the following action method:

public EmployeeDto Get(Guid employeeId)
{
...
}

My dilemma is whether it is appropriate to use the same DTO class for each action in the controller, or whether to create different DTOs for each action (eg, NewEmployeeDto, ExistingEmployeeDto).

One issue with using the same DTO is that some members of the DTO might not be appropriate (or redundant) for some actions. For example, the above instance of an EmployeeDto might be passed to the below action, but the Id member of it is meaningless, because the Id is only generated once the domain object is persisted to storage. The Id member should only be used when the Dto is sent back to the client.

public void CreateEmployee(EmployeeDto employee)
{
...
}

The above is not a problem, because we simply do not map the Id property of the DTO to our domain object, BUT I am wondering whether it would be better to create a new DTO called NewEmployeeDto that is only used in the CreateEmployee method and that looks like this instead:

public class NewEmployeeDto
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

The problem I see with this is that if requirements change and additional data requires adding to the DTO, then you might have to make the same change in three different classes : ReturnEmployeeDto, NewEmployeeDto, ExistingEmployeeDto. So the amount of maintenance is trebled in some cases.


Solution

  • It is fine to share the same DTO for the cases you've described and ignore some properties if they are meaningless.

    It would be overkill to split NewEmployee and ExistingEmployee in two separate classes just because a NewEmployee doesn't have an Id.