1

I was reading these best practices for Angular project specifically for understanding models and DTOs.

What I have understood in general from different resources and the above one also is that

  1. We should have DTO to match exact response structure coming from backend APIs
  2. We should have model classes to use to show data on the pages and for other operations

The problem is if I follow this approach I will have to then write mapper also for all the DTO to model classes which seems unnecessary effort.

I can easily achieve everything without breaking any design pattern with having any one of DTO or model classes.

Should I follow the best practice to have both DTO and model with so much additional code which is not serving too much of a purpose or can I go with just models or just DTOs being used on all levels and my Angular design will not be considered a bad design?

jonrsharpe
  • 1,311

2 Answers2

5

The point here is loose coupling: in your architecture with only one class used to represent both the API response and the user-facing data what are you going to do when:

  1. The requirements change for what is displayed to the user, but the API doesn't change?
  2. The API changes but the requirements for what is to be displayed to the user don't?

In both cases, you've now got a change which should affect only one layer, but ends up affecting more than one because you've coupled them by using the same class.

And before you go and blindly split every class into two and have a no-op mapper converting between the two, stop and think about how likely each of the scenarios listed above are for your project and where the balance lies.

0

This best practice guide seems to be written from a front end only point of view.

If you only write the front end, then you can't reuse the backends Models. So you have to write your own models, but call them DTOs. your front end logic goes in its own model which you call a Model but the backend would call a ViewModel

You don't really want to map your DTO directly to a Model. You should have a ViewModel for the entire page which might have data from several DTOs/Models plus extra bits about the state of dropdowns or darkmode/lightmode etc

Calling models ViewModels makes more sense to me, they are tightly coupled to your presentation layer.

eg.

SelectionPageViewModel
{
   CustomerDTO selectedCustomer
   CustomerDTO[] customers
   marketingOptIn = true
   OnClick() => {
     //do stuff
   }
}

You have no need for a CustomerViewModel/CustomerModel which is the same as a CustomerDTO so creating them would not be best practice. You DO need viewmodels for your pages to encapsulate the data (which may include DTO objects) and functionality of the View

If your view is so simple as to not need any extra data or functionality at all, you could just use the DTO. But I think I would make a ViewModel anyway, You are bound to need it. But I would just wrap a DTO rather than creating an identical object.

CustomerViewModel
{
    CustomerDTO customer
}

The alternate approach of using inheritance is out of style these days, but would also alleviate the need for a duplicate object and mapping

CustomerViewModel : CustomerDTO
{

}

the recommendation to "probably extend the DTO and format some fields" I think is just wrong. The place for that kind of thing is in the view Itself. eg.

<div> {{customer.date | date : 'yyyy-MM-dd'}} </div>
Ewan
  • 83,178