18.
Using a Serializer
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.
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
Whoops, an error! Please, try again later.
20 Comments
"It'll turn into a whole soap opera". Great lines like this every video, but this is my favorite!
You guys are so stinkin' funny!
And cute.
And smart.
Love your tuts!
that little angry face on the icon!
you're killin' me Smalls!
Hello
I install jms with
composer require jms/serializer-bundle
but when I add
new \JMS\SerializerBundle\JMSSerializerBundle(),
into AppKernel.php
in the
it's highlights and say "undefined namespace for SerializerBundle"
"undefined class JMSSerializerBundle"
How can I to fix this?
Hey Nina!
Hmm. Do you actually get an error when you run the code? Or is it simply that your editor isn't happy? If you get an error, it seems to me that somehow, the installation of the bundle was *not* successful. If the error is only in your editor, try clearing your browser's cache (I assume PhpStorm? One trick is to right click on vendor/ and select Synchronize 'vendor' to make sure it sees the new files).
Cheers!
I think installation was successful
> composer require jms/serializer
Using version ^1.8 for jms/serializer
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 5 installs, 0 updates, 0 removals
- Installing phpoption/phpoption (1.5.0): Loading from cache
- Installing phpcollection/phpcollection (0.5.0): Loading from cache
- Installing jms/parser-lib (1.0.0): Loading from cache
- Installing jms/metadata (1.6.0): Loading from cache
- Installing jms/serializer (1.8.1): Loading from cache
Writing lock file
Generating autoload files
> Incenteev\ParameterHandler\ScriptHandler::buildParameters
Updating the "app/config/parameters.yml" file
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::buildBootstrap
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache
// Clearing the cache for the dev environment with debug true
[OK] Cache for the "dev" environment (debug=true) was successfully cleared.
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installAssets
Trying to install assets as relative symbolic links.
-- -------- ----------------
Bundle Method / Error
-- -------- ----------------
[OK] All assets were successfully installed.
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installRequirementsFile
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::prepareDeploymentTarget
I try "to right click on vendor/ and select Synchronize 'vendor'" but it isn't help
editor highlights
public function registerBundles()
{
$bundles = [
new \JMS\SerializerBundle\JMSSerializerBundle(),
]
and
in the controller when I try to use
$user = $this->container->get('jms_serializer')
->serialize($user, 'json');
'jms_serializer' also highlights
and in the browser I have:
Whoops, looks like something went wrong.
(1/1) ClassNotFoundException
Attempted to load class "JMSSerializerBundle" from namespace "JMS\SerializerBundle".
Did you forget a "use" statement for another namespace?
in AppKernel.php (line 19)
at AppKernel->registerBundles()
in Kernel.php (line 450)
at Kernel->initializeBundles()
in Kernel.php (line 116)
at Kernel->boot()
in Kernel.php (line 168)
at Kernel->handle(object(Request))
in app_dev.php (line 29)
at require('C:\\OpenServer\\domains\\testovoe.rich\\web\\app_dev.php')
in router.php (line 42)
Hey Nina,
I see in the output you execute "$ composer require jms/serializer" but that's not a bundle, that is just a standalone library. So instead, you need to execute "$ composer require jms/serializer-bundle" and only then register your bundle with "new JMS\SerializerBundle\JMSSerializerBundle()," in AppKernel.php. Btw, notice that there's no leading slash before JMS namespace - I see you have it. It shouldn't cause problems, but just in case. So try to stick this installation: http://jmsyst.com/bundles/J...
Let us know if it doesn't help you.
Cheers!
Yes, thank you.
The hack for identical property error in JMS Serializer not worked for me somehow. I found another hack somewhere:
Add this in services.yml:
That's a good hack indeed :). Thanks for sharing Prakash S!
Hey! Is symfony serializer robust enough now?
Only started using serializers (jms ans symfony) recently.
Hey Mike!
First, LOVE your comments below - made our morning!
The Symfony serializer *is* robust enough now. Though, the JMSSerializer is a bit more configurable. For example, if you have a class and only want to expose *some* of the properties and/or maybe have a few "extra" properties (where the serializer calls a get* method to get the value for a field that is not a real value), you can do that in both (you'll use the Group annotation with the Symfony serializer to only serialize some fields). But that's about as far as the customizations go with the Symfony serializer... and I think that's by design (and kind of a good thing). If you have a resource (to use our fancy REST terms) and it begins to look *quite* different than your entity class, it might be better to create a new, "model" (non-entity) class and serialize this (e.g. create your new object and manually take the data from your entity and put it onto your model class - it's a bit of manual labor, but clear). The Symfony serializer pushes this approach a bit more. It's more work... but you also end up with clean model classes that exactly match your API (versus an entity class with a ton of annotations to modify it).
Honestly, I'm still on the fence a bit between the two. I'm tending to use the Symfony serializer more... but recently, the JMS serializer appears to have become "unabandoned" and is active again. Oh choices!
Cheers!
Hi Ryan,
what about now ? It's been two years since your answer.
Hey Kaizoku!
Haha, yea, it's interesting now :). JMSSerializer was abandoned for a long time. Now it is definitely not. However, the Symfony serializer is still more actively developed in my opinion, mainly because the lead developer of it is also the lead developer of API Platform (which uses it). I think both are solid choices, but I would go with the Symfony serializer at this point. I would also recommend looking into API Platform itself - we are definitely planning a tutorial on it at some point - it's amazing.
Cheers!
Thank you Ryan for your insight.
The fact that it's used by API Platform is a strong point. I found this interesting article on Github where API Platform explain their choices.
https://github.com/api-plat...
So unless you need a specific feature of JMS or you are already used to, I would go with Symfony Serialiser.
Hey Kaizoku, for the record, in our latest tutorial (Symfony4 forms) Ryan is using Symfony's Serializer instead of JMS. Anyway. I'll ping Ryan because hearing his opinion on this matter is interesting :)
Hey KnpUniversity
In the first time, Happy new year and all my best wishes for this new year (love, peace and more symfony code :p )
I have just a little question about the serialization, now with sf 3 is it better to use the Symfony serializer ?
And if it is yes is it correct to replace this method like that ?
Thanks again for your good work.
Hey Greg!
Wow - happy new year to you too - and all the same wonderful wishes :).
This is a GREAT question... and one that I struggle with myself. The JMSSerializer is still more powerful in my opinion than the Symfony serializer, with many more annotations to help you customize things. However, it's also basically abandoned, and much more complex. The Symfony serializer is still under active development and is a very high quality library!
So, right now, the best option comes down to a case-by-case basis, based on the developer. With JMSSerializer, since it has so many annotations, you can usually serialize your entities directly. If you need to tweak the name of a property (e.g. firstName should be "user_first_name" on JSON), that's easy to do. For more junior developers, I think its flexibility through all the annotations gives it a lower barrier to entry (the Symfony serializer does however have the @Groups annotation, which handles most cases - but isn't as user-friendly as the @Expose in JMS). For more senior developers, I recommend using the Symfony serializer. The trick is that if you have a JSON representation that looks sufficiently different than your entity, there are no annotations you can use that will help you "tweak" things so that you can serialize your entity directly. Instead, when I use the Symfony serializer, I usually create specific "model" classes and serialize them. For example, instead of serializing a Product entity, I'll create an API\Product class with the exact properties that I want in my JSON. I will then manually create the API\Product class from my Product entity's data and then serialize it. This is more work (and can seem like a lot to some developers). But, it also means that you have a really clean API: you can just open a directory full of simple PHP classes that each perfectly model a resource.
Phew! I hope that helps! About your code question, it's kind of right... but you're doing too much work! In the Symfony framework, Symfony comes with a pre-configured serializer service (you just need to active it in config.yml). Then you can just
$this->get('serializer')->serialize($data, 'json').Cheers!
Hey Ryan
Thank you for your answer, it is exactly what I am thinking. When I tried to use Symfony serializer in this tuto I got back all my entity with the entire user's relation (so included the password). JMSSerializer has a great powerful annotation to handle this problem.
I saw in the documentation the @Groups annotation for SF Serializer but I don't know yet how it is working ;)
thanks for the tip about the SF Serializer's configuration.
Again have a great year for all the KnpUniversity's team and make us like usually worderful tutos
Cheers
Awesome all around :D. Good luck and thanks for the nice words!
"Houston: no signs of life"
Start the conversation!