Address common confusion regarding DTOs for the same model in different contexts (eg. CRUD) #922
Softwaerewolf
started this conversation in
General
Replies: 1 comment
-
I have the same question- I saw another discussion and commented there first: #924 but it's essentially the same question. Is it expected that we create seperate DTO's for different contexts? Because the intro to this package sells the idea that we shouldn't have to do that because a single DTO can handle validation, resource, and DTO functionality at once, thereby eliminating entire directories of files. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
When trying to familiarise myself with this package and reading through the documentation and other discussions on this repository I noticed that there was one common question that keep repeating but with seemingly no straight-forward answer to the question.
The question was some variation of: How do I structure my DTOs so that certain fields are conditionally required in a given context (eg. required for update but not create)?
#506 #531 #340 #297 #240 #911
To give a more practical example, assume we have a
User
model and we create aUserData
DTO for the model it might look something like:This is pretty much in-line with the examples given in the documentation and videos produced by Spatie.
The problem arises when we encounter scenarios where we don't want to include every field, in a given context - for creating a
User
we don't have id, and a password may be required but only after we've verified the email address and only require them to provide a password when updating their email or password. Ok, so we change them topublic ?int $id, ... public ?string $password
.Now we've created our User and we've prompted them to set their password - but they type nothing and hit submit - this is perfectly acceptable because password is optional! But wait, we require them to set a password per our business rules!
Based on the replies to the aforementioned discussions and a somewhat quickly glossed over example provided from a non-public repository in this Laracon presentation by @freekmurze) it seems the generally accepted recommendation appears to be to create different DTOs per context. So actually what we should do is:
But this structure appears nowhere in the documentation or spatie/laravel-data-demo.
So I think I have correctly understood that the intended workflow is to create a DTO per "request" and then perhaps either a single DTO containing all properties for reading data (and adjusting it as required with Lazy attributes, include/exclude methods, include/excludeProperties method overrides) or opting for a DTO per type of read request too.
Please, correct me if I'm wrong. But if I'm correct, then I think this concept needs to be better explained in the documentation.
Beta Was this translation helpful? Give feedback.
All reactions