Chapters
36 Chapters
|
3:44:20
|
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!
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.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/core": "3.1.x-dev", // 3.1.x-dev
"doctrine/annotations": "^2.0", // 2.0.1
"doctrine/doctrine-bundle": "^2.8", // 2.10.2
"doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.4
"doctrine/orm": "^2.14", // 2.16.1
"nelmio/cors-bundle": "^2.2", // 2.3.1
"nesbot/carbon": "^2.64", // 2.69.0
"phpdocumentor/reflection-docblock": "^5.3", // 5.3.0
"phpstan/phpdoc-parser": "^1.15", // 1.23.1
"symfony/asset": "6.3.*", // v6.3.0
"symfony/console": "6.3.*", // v6.3.2
"symfony/dotenv": "6.3.*", // v6.3.0
"symfony/expression-language": "6.3.*", // v6.3.0
"symfony/flex": "^2", // v2.3.3
"symfony/framework-bundle": "6.3.*", // v6.3.2
"symfony/property-access": "6.3.*", // v6.3.2
"symfony/property-info": "6.3.*", // v6.3.0
"symfony/runtime": "6.3.*", // v6.3.2
"symfony/security-bundle": "6.3.*", // v6.3.3
"symfony/serializer": "6.3.*", // v6.3.3
"symfony/stimulus-bundle": "^2.9", // v2.10.0
"symfony/string": "6.3.*", // v6.3.2
"symfony/twig-bundle": "6.3.*", // v6.3.0
"symfony/ux-react": "^2.6", // v2.10.0
"symfony/ux-vue": "^2.7", // v2.10.0
"symfony/validator": "6.3.*", // v6.3.2
"symfony/webpack-encore-bundle": "^2.0", // v2.0.1
"symfony/yaml": "6.3.*", // v6.3.3
"symfonycasts/micro-mapper": "^0.1.0" // v0.1.1
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.4
"mtdowling/jmespath.php": "^2.6", // 2.6.1
"phpunit/phpunit": "^9.5", // 9.6.11
"symfony/browser-kit": "6.3.*", // v6.3.2
"symfony/css-selector": "6.3.*", // v6.3.2
"symfony/debug-bundle": "6.3.*", // v6.3.2
"symfony/maker-bundle": "^1.48", // v1.50.0
"symfony/monolog-bundle": "^3.0", // v3.8.0
"symfony/phpunit-bridge": "^6.2", // v6.3.2
"symfony/stopwatch": "6.3.*", // v6.3.0
"symfony/web-profiler-bundle": "6.3.*", // v6.3.2
"zenstruck/browser": "^1.2", // v1.4.0
"zenstruck/foundry": "^1.26" // v1.35.0
}
}
9 Comments
Hi,
I have one question regarding ApiPlatform and Doctrine. For example, I have a field that I want to expose only on
GET (item)but not onGET collection.Using s
erialization groups / #[Ignore]works for hiding the field in the response, but Doctrine still fetches it (e.g. via aLEFT JOINin the collection query).Example: I want to show dragonTreasures only on GET item, but not on GET collection (to avoid unnecessary joins).
Should I split my resource into two DTOs like
UserApiItemandUserApiCollection, or is there a better way to handle this in ApiPlatform (e.g. via providers, state options, or query customization)?Thanks!
Hey @Anas-M
Great question! The easiest solution would be to configure the relationship as
fetch: "EXTRA_LAZY"so Doctrine won't load it by defaultAnother option, but more complex is implementing a custom state provider for that entity
I hope it helps. Cheers!
Here my last update, what do you think about?
ProjectApi
ProjectBlockApi
Provider sends also:
Mapper add if:
Thanks for replying @MolloKhan,
Nice, I’ve never tried EXTRA_LAZY, I’ll check how it works. But what if I do something like:
$this->mapEntityToDto($entities, $resourceClass, ["operation" => 'GETCOLLECTION']);$this->mapEntityToDto($entities, $resourceClass, ["operation" => 'GET']);And in the Mapper, I don’t map dragonTreasures when it’s a collection, for example?
That's a good idea if the
EXTRA_LAZYoption doesn't fit your needs. The downside withEXTRA_LAZYis that it will execute one query for each element in the list, so if the list is big, it will consume a lot of resources, you need to fetch the list directly from the repository instead of the relationshipCheers!
Actually, trying to separate reading and writing didn't work for me, because when I add
stateOptions: new Options(entityClass: SomeClass::class),api platform serialization listener sets force_resource_class context parameter to operation's class value and it would be dto for writing. Then I'm getting a serialization error, saying something like 'Cannot access x field on dto object' on non-intersecting fields. But if I try old-fashioned way without dtos, I cat use custom controller getting entity of one class and returning entity of another one without problems, because in this case there is no need in stateOptions
Posted too soon)
Setting operation class explicitly to read dto makes it all work
Hey @Andrei-V!
I love that you tried this and reported back - I was very curious! So the solution is working well for you now? By "Setting operation class explicitly to read dto" can you mention exactly what you did? I'm curious - and it might help others.
Thank you :)
For POST and PATCH operations it works now, yes. My setup is like following (I add product to order and return the entire order for convenience):
Its also mandatory to add both output and class operation parameters
"Houston: no signs of life"
Start the conversation!