-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Serializer] Serializer improvements #14924
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
It's not the current philosophy of the Serializer component. Adding such features is IMO a bad idea:
You can already use groups to do that. What's the use case not covered with the existing feature?
It's IMO a bad idea to use annotations for that (encourage inconsistencies). The name converter system can already be used to do such things: http://symfony.com/doc/current/components/serializer.html#converting-property-names-when-serializing-and-deserializing
I don't like that kind of things:
Here again, this can definitely be done with groups: use Symfony\Component\Serializer\Annotation\Groups;
class Test
{
/** @Groups{"read"} */
public $foo;
/** @Groups{"read", "write"} */
public $bar;
} You can even adopt fine grained policy: use Symfony\Component\Serializer\Annotation\Groups;
class Test
{
/** @Groups{"user-read", "admin-read", "admin-write"} */
public $foo;
/** @Groups{"user-read", "user-write", "admin-read", "admin-write"} */
public $bar;
}
Agree. There is work in progress on that topic: #14844 (comment) |
For the |
However, an improvement I want to add is a What do you think? |
I didn't really explained why I think that the virtual properties are a good idea ... An example : /**
* @VirtualProperties({
* "foo": {
* @Readable(getter="notUsualSetter"),
* @Writable(setter="getUserFoo", security="is_granted('ROLE_SUPER_ADMIN')")
* },
* "bar": {
* @Expose(security="is_granted('ROLE_USER')")
* }
* })
* @NormalizePolicy(defaultExposition=false)
*/
class FooClass
{
...
} With the virtual properties, you can define for each method how it will be serialize and not just for the methods For the exposition features, they are principally made to simplify the development and to don't have to worry about the security questions. (For example the plainPassword of the FOSUserBundle is writable in some cases but not readable.) For the |
The Something like |
About |
@Ener-Getick |
This PR was squashed before being merged into the 3.1-dev branch (closes #17113). Discussion ---------- [Serializer] Add a MaxDepth option | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #14924 (comment), api-platform/core#104 (comment) | License | MIT | Doc PR | todo Add a max depth option during the normalization process. Especially useful when normalizing trees. Usage: ```php use Symfony\Component\Serializer\Annotation\MaxDepth; class MyObj { /** * @MaxDepth(2) */ public $foo; /** * @var self */ public $child; } use Doctrine\Common\Annotations\AnnotationReader; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); $normalizer = new ObjectNormalizer($classMetadataFactory); $serializer = new Serializer(array($this->normalizer)); $level1 = new MyObj(); $level1->foo = 'level1'; $level2 = new MyObj(); $level2->foo = 'level2'; $level1->child = $level2; $level3 = new MyObj(); $level3->foo = 'level3'; $level2->child = $level3; $result = $serializer->normalize($level1, null, array(ObjectNormalizer::ENABLE_MAX_DEPTH => true)); /* $result = array( 'foo' => 'level1', 'child' => array( 'foo' => 'level2', 'child' => array( 'child' => null, ), ), ); */ ``` * [x] Metadata support * [x] `@MaxDepth(2)` annotation and loader * [x] XML loader * [x] YAML loader * [x] Delegate recursive normalization at the end of the process * [x] Use constants with Late Static Binding in the abstract class instead of raw strings * [x] Move common logic to the abstract class /cc @mRoca @csarrazi Commits ------- a44bead [Serializer] Add a MaxDepth option
This PR was squashed before being merged into the 3.1-dev branch (closes #17113). Discussion ---------- [Serializer] Add a MaxDepth option | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony/symfony#14924 (comment), api-platform/core#104 (comment) | License | MIT | Doc PR | todo Add a max depth option during the normalization process. Especially useful when normalizing trees. Usage: ```php use Symfony\Component\Serializer\Annotation\MaxDepth; class MyObj { /** * @MaxDepth(2) */ public $foo; /** * @var self */ public $child; } use Doctrine\Common\Annotations\AnnotationReader; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); $normalizer = new ObjectNormalizer($classMetadataFactory); $serializer = new Serializer(array($this->normalizer)); $level1 = new MyObj(); $level1->foo = 'level1'; $level2 = new MyObj(); $level2->foo = 'level2'; $level1->child = $level2; $level3 = new MyObj(); $level3->foo = 'level3'; $level2->child = $level3; $result = $serializer->normalize($level1, null, array(ObjectNormalizer::ENABLE_MAX_DEPTH => true)); /* $result = array( 'foo' => 'level1', 'child' => array( 'foo' => 'level2', 'child' => array( 'child' => null, ), ), ); */ ``` * [x] Metadata support * [x] `@MaxDepth(2)` annotation and loader * [x] XML loader * [x] YAML loader * [x] Delegate recursive normalization at the end of the process * [x] Use constants with Late Static Binding in the abstract class instead of raw strings * [x] Move common logic to the abstract class /cc @mRoca @csarrazi Commits ------- a44bead [Serializer] Add a MaxDepth option
The symfony serializer is a great tool but it's probably underused now.
2.7 introduces the groups and I think that we could think to else fields we could create !
Firstly, the fields exposition isn't really present now. I suggest to add an
Expose
config (definable totrue
/false
) and the possibility to change a field serialized nameExportsAs
.It could also be useful to implement virtual properties.
Besides that I think it's important to have the choice to split readable field and writable fields:
So I suggest to have a normal policy
NormalizePolicy
, a readable policyReadablePolicy
and a writable policyWritablePolicy
on classes that define a default exposition, a default security (expression, overwritable) and a global security (expression, not overwritable).We should develop maybe a verification mechanism too with a type verification and normalization.
If you don't see what I mean, I created some annotation classes : https://github.com/Ener-Getick/symfony/tree/ticket_14924/src/Symfony/Component/Serializer/Annotation.
Please give your feedbacks.
The text was updated successfully, but these errors were encountered: