Easyadminbundle: [RFC] [3.0] Easier form DTO support

Created on 8 May 2020  路  10Comments  路  Source: EasyCorp/EasyAdminBundle

I know this is an _nth_ version of this feature request, but I definitely would like DTOs to be first-class-citizens in many apps using admin backends today.

My goal in the apps I develop these days is to get rid of setters and use proper mutators to avoid data corruption (because of how entities are used in the Forms component) and inconsistent behavior documentation (rich mutators document the app while setters don't) for entities. DTO is the best solution for that.

In Compotes, I implemented a really straightforward solution that the user can implement in a few minutes, and it actually would just need a new "maker command" to generate the necessary boilerplate code with something like make:dto {dto name} {class name} and make:admin-crud --with-dto {entity name} {dto class} or such.
However, this is only for EA2, therefore I consider this feature to be "obsolete" right now, since EA2 will be somehow "frozen" after EA3 is released.

Right now with EA3 alphas, I intend to recreate this feature, but I face many walls that are kinda hard to pass through (hence the last PRs I made, to simplify the work somehow and fix some bugs).

Latest wall when I'm writing this: it's impossible to execute $entityDto->setInstance(...) with something else than the entity class, so I can't override it with a DTO. And I can't use the DTO class in the getEntityFqcn() method since it would only accept an entity.

Any chance the feature concept is accepted before moving to technical proposals phase?

feature wontfix

Most helpful comment

@javiereguiluz I also am not happy about the decision. But, of course, I respect that 馃檭

I don't like that because it forces me to stick to EA2, since there is still possible to have some DDD.
But it's a pity to not be able to upgrade to EA3 (I was actually waiting for it). And, as you suggested, I guess I'll have to choose some other library, at least for my next projects (I am stubbornly not going to renounce to the benefits of DDD).


However, as @ragboyjr mentioned, having final class everywhere is too much of a limit. And I strongly agree.

final is intended for classes that are never ever going to change, usually concrete implementations (at project level most of the times).

In general:

I acknowledge that it is a good practice to add final by default; but this is done to be able to remove it later on, once the scope of a class is clearer and when it's clear that a class should be extendable. More or less the same good practice of having private methods if not explicitly necessary to expose them, as public, or make overridable, as protected.

In a framework:

It's hard to forecast all the use cases of a library, because its purpose is not concrete as a specific project. Hence it's a better practice to not add final class as long as one is not absolutely sure that that class must never be touched/altered (like core classes that might break anything and are not business of the user, or specific/concrete classes).

Another example is what we do in Honeybee, our DDD+CQRS framework: we use final class just for the implementation of the ServiceLocator, because we are sure that nobody should touch it, ever.
We add final just when implementing classes in specific projects that make use of our framework.

The point is:

Removing it might open the doors to adapting & using EA3 also for projects where it does not fit perfectly.
Would it be great if EA3 would not block the user, but rather allow a high degree of extendibility.

According to my (hopefully clear) opinion, would you think that it makes sense to remove final from most of the EA3 classes, leave the freedom to its users, and be strict just on few selected (core or concrete) classes?
I believe it would still allow a DDD future for EasyAdmin 馃帀.

All 10 comments

@javiereguiluz any chance you will answer on that problem?
I already faced with that trouble in EA3 version. In EA2 it is possible via overriding createEditForm, updateEntity and persistEntity

I'm in a similar boat as well. I'm overall really enjoying EA3, but short of reimplementing all of the final classes, adding seamless DTO support is near impossible.

This is hack city, but I got the following to work with EA3 for DTO support:

Update: https://gist.github.com/ragboyjr/2ed5734eb839483ca22892f6955b2792

For any entity that you want to use DTOs, just extend this class instead and implement the abstract functions and you have clean DTO config.

@ragboyjr don't worry, DTO support for EA2 is already a bunch of hacks, but it works very well :)

Do you think this solution is possible with a trait instead of inheriting?

I think so, but only if you forced some convention around the DTO and entities so you could automatically discover the DTO class from the entity name. I'm using inheritance since that was the main extension point provided by EA Admin 3 for the CrudController so it made it a bit more seamless to follow suit. Also, the inheritance allows me to specify abstract fns for the DTO to Entity mapping.

As EA is a CRUD system, in my implementations I relied on specific interfaces in order to make sure the DTO methods could be abstracted in some way.

Also, the inheritance allows me to specify abstract fns for the DTO to Entity mapping

You can define abstract methods in traits 馃槈

I've made a decision about this, and I'm afraid you are not going to like it. We're not going to add support for DTOs. Sorry!

Why? Because I never use DTOs with Symfony forms and I know nothing about that, so I can't review things before merging and I can't debug anything when errors happen. You may think that this is not a problem because "the community" will take care of everything, but after several years of maintaining this project, I know it won't happen.

Finally, a comment about this: I'm not judging you or your technical decisions. Using DTOs (or not using them) doesn't make you a better or worse profesional. I think you should use in your projects whatever you want or like. Everybody is welcomed in the Symfony community, whatever their choices.

I'm sorry this project can't help you and your projects. Please, check if other admin generators, such as SonataAdminBundle or the API Platform admin support this feature. Thanks!

I don't like that decision very much indeed, it's just sad because this still makes EA highly coupled with Doctrine ORM and still contains no built-in solution to prevent Doctrine from its usual side-effects (like using Doctrine events on big projects).

But it's not my package, and you seem to have thought about it a lot, so won't argue more.

@javiereguiluz I also am not happy about the decision. But, of course, I respect that 馃檭

I don't like that because it forces me to stick to EA2, since there is still possible to have some DDD.
But it's a pity to not be able to upgrade to EA3 (I was actually waiting for it). And, as you suggested, I guess I'll have to choose some other library, at least for my next projects (I am stubbornly not going to renounce to the benefits of DDD).


However, as @ragboyjr mentioned, having final class everywhere is too much of a limit. And I strongly agree.

final is intended for classes that are never ever going to change, usually concrete implementations (at project level most of the times).

In general:

I acknowledge that it is a good practice to add final by default; but this is done to be able to remove it later on, once the scope of a class is clearer and when it's clear that a class should be extendable. More or less the same good practice of having private methods if not explicitly necessary to expose them, as public, or make overridable, as protected.

In a framework:

It's hard to forecast all the use cases of a library, because its purpose is not concrete as a specific project. Hence it's a better practice to not add final class as long as one is not absolutely sure that that class must never be touched/altered (like core classes that might break anything and are not business of the user, or specific/concrete classes).

Another example is what we do in Honeybee, our DDD+CQRS framework: we use final class just for the implementation of the ServiceLocator, because we are sure that nobody should touch it, ever.
We add final just when implementing classes in specific projects that make use of our framework.

The point is:

Removing it might open the doors to adapting & using EA3 also for projects where it does not fit perfectly.
Would it be great if EA3 would not block the user, but rather allow a high degree of extendibility.

According to my (hopefully clear) opinion, would you think that it makes sense to remove final from most of the EA3 classes, leave the freedom to its users, and be strict just on few selected (core or concrete) classes?
I believe it would still allow a DDD future for EasyAdmin 馃帀.

Absolutely agree. Without that only simple crud-based application can use easy admin

Was this page helpful?
0 / 5 - 0 ratings