Chapters
27 Chapters
|
2:54:11
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.1.3
Subscribe to download the code!Compatible PHP versions: ^7.1.3
-
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.
This tutorial works great for Symfony 5 and API Platform 2.5/2.6.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/core": "^2.1", // v2.4.3
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.10.2
"doctrine/doctrine-bundle": "^1.6", // 1.11.2
"doctrine/doctrine-migrations-bundle": "^2.0", // v2.0.0
"doctrine/orm": "^2.4.5", // v2.7.2
"nelmio/cors-bundle": "^1.5", // 1.5.5
"nesbot/carbon": "^2.17", // 2.19.2
"phpdocumentor/reflection-docblock": "^3.0 || ^4.0", // 4.3.1
"symfony/asset": "4.2.*|4.3.*|4.4.*", // v4.3.11
"symfony/console": "4.2.*", // v4.2.12
"symfony/dotenv": "4.2.*", // v4.2.12
"symfony/expression-language": "4.2.*|4.3.*|4.4.*", // v4.3.11
"symfony/flex": "^1.1", // v1.21.6
"symfony/framework-bundle": "4.2.*", // v4.2.12
"symfony/security-bundle": "4.2.*|4.3.*", // v4.3.3
"symfony/twig-bundle": "4.2.*|4.3.*", // v4.2.12
"symfony/validator": "4.2.*|4.3.*", // v4.3.11
"symfony/yaml": "4.2.*" // v4.2.12
},
"require-dev": {
"symfony/maker-bundle": "^1.11", // v1.11.6
"symfony/stopwatch": "4.2.*|4.3.*", // v4.2.9
"symfony/web-profiler-bundle": "4.2.*|4.3.*" // v4.2.9
}
}
15 Comments
I would like to set the logged in user in the constructor. The problem is I can't and don't want to simply inject services into the entity. And in the DataPersister the object was already initialized. Any ideas?
`
`
Hey Wondrous!
Sorry for the slow reply! We're usually much faster - that's my bad - prepping for a conference next week!
This is an interesting question/problem. First, when using Doctrine (ignore API Platform for a moment), the constructor is only called ONE time: when you originally CREATE the object. Once it's been persisted to Doctrine, on future requests, when you query for that object from the database, the constructor is NOT called. That's by design: Doctrine wants it to feel like your object is created just once... then is kind of "put to sleep" in the database and woken up later.
You may have already known the above stuff :). I mention it because it narrows the scope. The question now is: how can we pass a custom argument to the constructor when our object is originally created - e.g. when a POST request is made to /api/cheeses? That's a question for the serializer - and though I haven't done this before, I think the answer is here: https://symfony.com/doc/current/components/serializer.html#handling-constructor-arguments
You should be able to accomplish this by creating a custom context builder - https://symfonycasts.com/screencast/api-platform-security/service-decoration - and if the "resource class" is currently the target class, you could add that
AbstractNormalizer::DEFAULT_CONSTRUCTOR_ARGUMENTSkey to the context, set to the currently-logged-in user.Let me know if you end up trying this and if it works out - it's an interesting problem!
Cheers!
Hi, I don't understand why we use "SeriallizedName" annotation. Doesn't "Serialize" mean that we are *reading* data (i.e. from Object to Format)? So why we use "Serialzed" and not "Deserialized" in setting property?
Hey @Danilo Di Moia!
That's an excellent question and perspective! It had not occurred to me before!
The truth is that SerializedName would be used for both reading data and/or writing data. In this example, we added the SerializedName above our
setTextDescription()method. So naturally (since this is a setter, so it's only used for writing data), the SerializedName is actually more of a "deserialized name" as you suggested :). If we had put this same SerializedName on a getTextDescription(), then it would only be used for "reading" data.So it really controls the named that's used for both serialization and deserialization. But if you are adding it to a getter or setter method like we did, then, of course, it really only applies to either read (for the getter) or write (for the setter). However, if you added it to a property (imagine
@SerializedName("cheeseDescription")above the$descriptionproperty), then the field would be calledcheeseDescriptionfor both reading and writing).I hope that explains why it has just this one name (SerializedNamed)... even though that's imperfect in 1/2 of the situations :P.
Cheers!
Just trying to add some API capability to existing Symfony 4.4 project but probably missed something in config. On simple POST operation got an error message:
<br />"@context": "/api/contexts/Error",<br /> "@type": "hydra:Error",<br /> "hydra:title": "An error occurred",<br /> "hydra:description": "Format 'jsonld' not supported, handler must be implemented",<br />And can't find how to implement handler and where :(
Hey @isTom!
Hmm. You *will* need to add some config for API Platform - but it's pretty basic - https://github.com/symfony/... - and it doesn't include any "formats" config... you should get several formats out-of-the-box without needing any config. Are you also using FOSRestBundle by chance? I'm asking because, as far as I can tell, THAT is the library that is throwing this error - https://github.com/FriendsO...
Cheers!
Hello weaverryan !
I described the problem with more details in Stackoverflow question
https://stackoverflow.com/q....
Hey @isTom!
I replied over there. The tl;dr is: uninstall/disable FOSRestBundle to see if it fixes things or at least gives you a different error.
Cheers!
Hi, i have lots of properties i need to make immutable but i also need to use the SerializedName() to alter the camelcase that API Platform generates. When i remove the setter the property disappears completey from the POST even though it's still in the group. Any ideas how i can achieve this?
Thank you
Hey Tom!
Sorry for the slow reply! Hmm, by "immutable" - I think you are referring to "I want them immutable in my app/PHP" versus "I want them immutable in my API", correct? If you (for whatever reason - e.g. design reasons) want to not have setter methods, then you *can* instead have each property as a constructor argument - each argument name needs to match the field name in the POST (that's how the serializer matches each input field with the arguments in your constructor). I don't like doing it this way... because iirc, if the user fails to send a required constructor field, they will get a serialization error - which is still a 400 error, but not as clear as a validation error. Let me know if that helps... or if I've completely answered the wrong question :).
About the SerializedName() part, if you are consistently changing how your "casing" is done, you can also do this on a global level - https://symfony.com/doc/cur...
Cheers!
Hey Guys,
We have made the title property immutable but in the documentation for the PUT operation, the key "title" is still present. So we can believe that it is possible to change the title ...
Is there a solution to this problem?
Many thanks
Hey Mykl
Nice catch! I had to do some research to figure it out what's happening. The problem is that the field "title" has the group "cheese_listing:write", so all http methods will let you pass in that field. What you have to do is to only allow the POST method to access to it by defining a collection operation.
So then you can replace the group "cheese_listing:write" by "cheese_listing:collection:post" on the title property
Cheers!
Thank you Diego !
Hey Guys,
This is a bit off topic, but in phpstorm, is there a way to get closing quotes and brackets in the annotations? For example, if I type
{ or ", then} or "this would immediately be inserted.Hey Skylar,
Not sure about this feature out of the box like activating it with a tick... but I use PhpStorm's Live Templates for this. You can create your own template where you declare that when you write "{" and press "Tab" for example - it expands to "{$END$}" where "$END$" is a point where you will have the cursor. You can configure the action when it will trigger like pressing Tab, enter, etc. and in what file extensions it will work, like in ".php", or ".yaml" files.
I hope this helps, just play with it a bit.
Cheers!
"Houston: no signs of life"
Start the conversation!