Chapters
48 Chapters
|
5:13:28
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
42.
DTO Class Organization
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
This tutorial also works great with API Platform 2.6.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=8.2",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/core": "^2.1", // v2.5.10
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.12.1
"doctrine/doctrine-bundle": "^2.0", // 2.1.2
"doctrine/doctrine-migrations-bundle": "^3.0", // 3.0.2
"doctrine/orm": "^2.4.5", // 2.8.2
"nelmio/cors-bundle": "^2.1", // 2.1.0
"nesbot/carbon": "^2.17", // 2.39.1
"phpdocumentor/reflection-docblock": "^3.0 || ^4.0 || ^5.0", // 5.2.2
"ramsey/uuid-doctrine": "^1.6", // 1.6.0
"symfony/asset": "5.1.*", // v5.1.5
"symfony/console": "5.1.*", // v5.1.5
"symfony/debug-bundle": "5.1.*", // v5.1.5
"symfony/dotenv": "5.1.*", // v5.1.5
"symfony/expression-language": "5.1.*", // v5.1.5
"symfony/flex": "^1.1", // v1.21.6
"symfony/framework-bundle": "5.1.*", // v5.1.5
"symfony/http-client": "5.1.*", // v5.1.5
"symfony/monolog-bundle": "^3.4", // v3.5.0
"symfony/security-bundle": "5.1.*", // v5.1.5
"symfony/twig-bundle": "5.1.*", // v5.1.5
"symfony/validator": "5.1.*", // v5.1.5
"symfony/webpack-encore-bundle": "^1.6", // v1.8.0
"symfony/yaml": "5.1.*" // v5.1.5
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.3", // 3.3.2
"symfony/browser-kit": "5.1.*", // v5.1.5
"symfony/css-selector": "5.1.*", // v5.1.5
"symfony/maker-bundle": "^1.11", // v1.23.0
"symfony/phpunit-bridge": "5.1.*", // v5.1.5
"symfony/stopwatch": "5.1.*", // v5.1.5
"symfony/twig-bundle": "5.1.*", // v5.1.5
"symfony/web-profiler-bundle": "5.1.*", // v5.1.5
"zenstruck/foundry": "^1.1" // v1.8.0
}
}
6 Comments
Hey there . What if I want to use a DTO input class for the owner entity also? I couldn't find any cast about embedded relations (like https://symfonycasts.com/sc... for DTO classes.
Hey @solverat!
I am... actually not sure :). Have you tried it yet and run into any issues? What exactly do you want to accomplish? The input/output DTO's are super interesting - but even the people at API Platform know they have some limitations.
Cheers!
Hi Ryan,
I don't think it is necessary to move the mapping logic to the DTO class. Isn't it a responsibility of the transformer and denormaliser?
I find this a bit unexpected as well. I thought DTOs were supposed to be super lightweight to the point of often not even having any methods at all, just public properties, but this video guides us in the opposite direction of making them a bit "fatter".
Furthermore, all original classes (two Transformers and a Denormalizer) are still kept for Api Platform to do it's magic – only transformation logic is moved. On one hand, them remaining there seems to defeat the purpose of moving the logic out of them. On the other hand though, it probably allows turning them into more generic services, not tied to specific Entity or DTO classes (I just remembered I have a project which does exactly that checked out on my disk).
One other thing I find somewhat quirky with these videos is Ryan's quite consistent use of pre-PHP7.4 syntax (e.g. no typed properties) in them, even though PHP 8.0 had already been released (or almost released) at the time they were filmed, and 7.4 had already been alive for a year. There are additional nuances you get to watch out for when using strict typing in your code. For example,
$cheeseListing->setOwner($this->owner);inCheeseListingInputwill cause an error if$owneris properly typehinted in both classes, but not passed in the input. Extra care is needed to avoid situations like this, which would most likely add even more "fat" to the DTOs.Tuan Vu Yes, I agree. Great response, thank you.
Hey Tuan Vu!
I'm happy either way :). I really think this comes down to a personal preference. Though if I *did* keep the logic in the transformer, etc, I would probably isolate it to a private function, just to keep things organized and readable. If you like that better, I think that is a great solution.
Cheers!
"Houston: no signs of life"
Start the conversation!