We have a single solution Visual Studio web application with multiple projects.
One of the projects (Services project) has APIs for our App clients (Android/iOS). There's separate project for MVC application that powers our Desktop and Mobile website. There's one project for DTO that has POCO classes for request/response objects. One project is for Entities that has all our business Entities.
The ViewModel classes are saved in the MVC/UI project itself. The Adapter classes (to convert DTO to entities and entities to DTO) are in services project and in MVC/UI project respectively.
For Android/iOS the request-response looks like: Request parameters come to the services project and are mapped as DTO through service's project adapters, this DTO is converted to Entity and passed to BL, DAL, DB/MicroServices. The response comes back to the services project as Entity and gets mapped to a DTO through Adapter classes. This DTO is passed as response to the clients.
For website (mobile & desktop) the request-response looks like: Request parameters come to the MVC/UI project and are mapped as DTO through MVC/UI project adapters, this DTO is converted to Entity and passed to BL, DAL, DB/MicroServices. The response comes back to the MVC/UI project as Entity and gets mapped to a ViewModel through Adapter classes. This ViewModel is passed to the view which generates the HTML and passes HTML to the clients.
The primary difference between DTO and ViewModel we have is that DTO are flat objects while ViewModel might have nested objects too. Also, ViewModel might have composite fields i.e. fields like FullName (combination of FirstName and LastName) while DTO will only have simple properties like FirstName, LastName. The reason is that we want to give flexibility to Apps i.e. they might want to show FirstName in a different font as compared to LastName.
There are few queries we have regarding the above architecture?
- Should we have different projects for Web API and MVC/UI?
- Should we have ViewModel only for MVC applications and return plain DTO to the Apps and let them build ViewModel for their UI?
- Is it correct to accept only DTO from the clients and return back only DTO/HTML to them? Is it necessary to convert DTO to entity for each request and vice-versa for each response?
- The adapter classes (to convert DTO to entity and vice-versa), it should be in a separate project OR same project?