Chapters
28 Chapters
|
2:51:42
|
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.2",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/core": "^3.0", // v3.0.8
"doctrine/annotations": "^1.0", // 1.14.2
"doctrine/doctrine-bundle": "^2.8", // 2.8.0
"doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.2
"doctrine/orm": "^2.14", // 2.14.0
"nelmio/cors-bundle": "^2.2", // 2.2.0
"nesbot/carbon": "^2.64", // 2.64.1
"phpdocumentor/reflection-docblock": "^5.3", // 5.3.0
"phpstan/phpdoc-parser": "^1.15", // 1.15.3
"symfony/asset": "6.2.*", // v6.2.0
"symfony/console": "6.2.*", // v6.2.3
"symfony/dotenv": "6.2.*", // v6.2.0
"symfony/expression-language": "6.2.*", // v6.2.2
"symfony/flex": "^2", // v2.2.4
"symfony/framework-bundle": "6.2.*", // v6.2.3
"symfony/property-access": "6.2.*", // v6.2.3
"symfony/property-info": "6.2.*", // v6.2.3
"symfony/runtime": "6.2.*", // v6.2.0
"symfony/security-bundle": "6.2.*", // v6.2.3
"symfony/serializer": "6.2.*", // v6.2.3
"symfony/twig-bundle": "6.2.*", // v6.2.3
"symfony/ux-react": "^2.6", // v2.6.1
"symfony/validator": "6.2.*", // v6.2.3
"symfony/webpack-encore-bundle": "^1.16", // v1.16.0
"symfony/yaml": "6.2.*" // v6.2.2
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.2
"symfony/debug-bundle": "6.2.*", // v6.2.1
"symfony/maker-bundle": "^1.48", // v1.48.0
"symfony/monolog-bundle": "^3.0", // v3.8.0
"symfony/stopwatch": "6.2.*", // v6.2.0
"symfony/web-profiler-bundle": "6.2.*", // v6.2.4
"zenstruck/foundry": "^1.26" // v1.26.0
}
}
25 Comments
Hey. Cool series.
I noticed a small issue
After successful update of
username, propertynameof Treasure remained the same.I can say even more. PUT request
has response code:200, but
nameis not changed.For some reason I was missing
setNameinDragonTreasureMystery solved ))
oh heck yeah, thanks! Was having the same thing and it was stumping me.
Since I was dealing with PATCH instead of PUT because of the recent api-platform changes I was looking into that direction.
but setName() was removed when we set it in the constructor. The tutorial made it - on purpose - only settable once during creation. You get no error when you do try to change it later though.
Again, thanks, was pulling my hear out!
(Didn't even try it yet but the moment I read your comment the lightbulb went off in my head :wink:)
Hey Joris-Mak,
Thanks for mentioning that was a useful comment for you!
Cheers!
Hey @seshy,
Awesome news! Such things happens sometimes! Keep going!
Cheers!
Hi Ryan,
Thank you so much for yet another fantastic course!
While coding along with the course, I'm now struggling with changing the owner's
username. Multiple issues / questions to that:#[Assert\NotBlank()]annotation prevents updating theUserobject without providing thedescription. Which is actually correct. But how does this work for you? I checked out the code: MyUser#description's annotations appear to be identical to yours.PUTreplaces the object, which means: It removes the current one and creates another one. Which is a correct behaviour as well. But also here: How does it work for you? :)PUTand notPATCHin this case?Best,
Ilya
Hey Automatix,
Hm, I don't see the User object has a description field in this video. Are you talking about a different video? Could you link me?
1) But it depends on what you update. If you update User object - that makes sense you have validation error if your User#description field has
#[Assert\NotBlank()]. But if you update a different object that has relation to User - that may require#[Assert\Valid()]constant on the$userproperty, as it's mentioned in this video for$ownerproperty.2) yes, it may end up into a DB error if your field is not nullable in the DB. To make it work, you should set the field to an empty string at least and then it should not be a DB error. It depends on which behavior you want. Also, sometimes, it may depend on the DB SQL server or DB server version.
3) Mostly because PUT and PATCH operations in the ApiPlatform that is used in this video works identical, i.e. no difference. Since ApiPlatform v4 they indeed work different, so if you don't want to set all the fields that are not specified in the PUT request to NULL on the request - use PATCH or specify the field explicitly :) See the note in this section https://symfonycasts.com/screencast/api-platform/operations#put-vs-patch for more details.
I hope that helps!
Cheers!
Hi,
I'm trying to figure out how to prevent existing embedded entities from being updated in a POST request. However, new entities should be able to be created.
To stay with the example from the cast.
If I create a new DragonTreasure via POST then
POST /api/treasuresPOST /api/treasuresPOST /api/treasuresI haven't yet found a good way to differentiate between creating and updating a nested entity without implementing various things myself.
What is the correct way in API Platform to implement this?
Hey @rabbar!
I can see that you understand the mechanism of how this all works well! To summarize:
Is that accurate? If so, I think it makes sense. But in Api Platform's eyes, these are all just valid ways to change data. I'm not entirely sure how to handle this. The closest I got was to allow updating, but to add a validation check that the API client does or doesn't have permission to update this user. This is not exactly the same, but it's related and can maybe offer some inspiration: https://symfonycasts.com/screencast/api-platform-extending/simpler-validator
Let me know if you have any luck, I'd love to know!
Cheers!
Yes.
I followed your advice with the validator. It works so far.
I have left out the checking of relation collections for now because it doesn't play a role in my case and would only make things unnecessarily complicated.
hi,
why does the other way (from user perspective) not working?
PATCH /api/users/1Result:
Does it only work for OneToMany Relations?
Hey @mjk!
Sorry for my very slow reply! I can see what you want to do and it makes sense. This may be related and help: https://github.com/api-platform/core/issues/5559#issuecomment-1518595331 - let me know if it does!
Cheers!
At 4:06 Timestamp,
I think in my code , sending the data same as below also works , without passing @id as mentioned in the video, and one more thing Is that it seems not working when I'm using PUT, but when using PATCH, it works, could you please explain why ?
Good morning everyone,
First of all, thank you for the great tutorial :)
I'm trying to change the username via the Treasure entity in the User entity.
PUT https://dev.symfonycast-api-start.wip/api/treasures/2
It shows as an error that in Treasure the name and description fields cannot be empty. I thought PUT only changed the fields that were passed in the payload?
Historically API Platform would essentially treat PUT operations as PATCH operations and be used for partially updating resources. I believe in latest versions of API Platform the PUT operation now actually acts like a true PUT, where where all non-specified fields are removed (set to null) and PATCH is the method you should use if you want to partially update a resource by specifying only the fields you want to change.
tldr; when these videos use PUT you should use PATCH instead.
Hey @creativx007
As @opalint mentioned, ApiPlatform changed how they used to treat PUT operations, we have a little warning note in this chapter https://symfonycasts.com/screencast/api-platform/serializer?playAt=269#adding-a-virtual-textdescription-field
Hello!
I'm having issues with a case like the one in this chapter, but with a special feature.
I have a Contract entity that has a OneToMany relationship with Condition.
There are several entities that inherit from Condition: CityCondition, DataCondition, etc.
When I try to post a Contract embedding, for example, CityCondition, it gives an error because it's trying to instantiate the abstract class Condition, even though I'm specifying through IRI that it's a CityCondition.
Any ideas? Is this not allowed, or am I missing something?
Thanks!
Posted JSON
Error:
Hey @Oleguer-C!
Hmmm. I don't have any experience with Doctrine inheritance and the serializer. To debug this, I'd first try to get a stacktrace of where this error comes from. Then maybe we can work backwards from the source to see if / how you could tell the serializer that you want a
CityConditionobject specifically (passing the@typewas a good idea... but apparently isn't enough!).Cheers!
Thank you very much!
After managing to decorate the AbstractItemNormalizer class to use the '@type' field, I realized that it actually works by default, and the problem was that I hadn't configured the 'typeProperty' field in the 'DiscriminatorMap' annotation on the abstract class.
I'm attaching the result in case it can be useful to someone.
Cheers!
Fantastic! Thank you for sharing that!
Hi guys but what's about the case when we have one-one relation, for example User-Profile.
We create a user with a profile, But the profile scope requires iri of the user /api/user/??? It works only if I have IRI user id. All relations has
cascade: ['persist']idea how to solve it?Hey,
IIRC if you are persisting a new object you don't need to set back relation to it, I mean you User payload should be like
That should be enough to create related objects at once.
Cheers!
When I want to change username and name of treasure I receive error:
"hydra:description": "name: Describe your loot in 50 chars or less\ncoolFactor: This value should be less than or equal to 10.",I know that is setted #[Assert\NotBlank] but it's just the same like you have code?
Hey @Szymon!
It looks like the data on that treasure is STARTING invalid - like the coolFactor in the database is somehow already greater than 10. And so, even though you’re not changing that field, it fails validation. I think for the treasure’s name I may have a bug on the fixtures that randomly sets a name that’s longer than 50 - so that is likely the cause of that error. I might (?) have some problem also with coolFactor!
So, just a data error on the database - and probably my fault. On production, thanks to validation, that data would never be able to get into this invalid state.
Cheers!
Yeah, that is the reason, changing the
getDefaults()inDragonTreasureFactory.phpto something like:`protected function getDefaults(): array
will fix it.
Regards!
"Houston: no signs of life"
Start the conversation!