Skip to content
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

Add support for multiple exclusion policies, add Default group (enabled by default) #140

Closed
wants to merge 2 commits into from

Conversation

Seldaek
Copy link
Contributor

@Seldaek Seldaek commented Jun 28, 2012

Changes/Additions:

  • All properties without a group defined are now considered to have the group "Default" (consistent with Validator component)
  • By default, the serializer only takes the group "Default" (consistent with Validator component) - possible to change by overriding Serializer::createDefaultExclusionStrategy
  • Setting an empty group array enables only "Default" - to disable groups completely one can use Serializer::setExclusionStrategy(null)
  • Added Serializer::addExclusionStrategy that adds a new one in the chain, but keeps the current ones (useful to add custom strategies safely)

Fixes #107

@@ -44,26 +46,37 @@ public function setExclusionStrategy(ExclusionStrategyInterface $exclusionStrate
$this->exclusionStrategy = $exclusionStrategy;
}

public function addExclusionStrategy(ExclusionStrategyInterface $strategy)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really comfortable with adding this here.

If this is valuable, then we need to think about adding a dedicated builder object for the serializer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well we actually use it already.. because in one case we have some weird strategy that depends on a who sees the data, and we exclude fields based on that, so on some actions we just add that strategy to it. I don't see what a builder would bring apart from more code to write.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A builder would separate the concerns, and make the code more readable.

$container->get('serializer.builder')->enableGroups(array('Foo'))->setVersion('1.0')->addExclusionStrategy($foo)->build();

Right now, the serializer is container scoped, and when you retrieve it, and start adding strategies, you don't really know what internal state it is in. We would also need to add methods to reset strategies because it is stateful at the moment. The more methods we add the more complicated this gets.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do see your point, and I agree it's probably safer. It takes away a lot of convenience though when using FOSRestBundle that means you can't just configure the serializer and then return an array of data, you'll have to create a view and give it the serializer (which isn't even possible right now, but fixable). Anyway if that's the only problem you have with the PR I happily fix it.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be doable to re-add the convenience methods. Maybe we need to allow people to configure several different serializers (in JMSSerializerBundle), and then add an annotation to the FOSRestBundle to tell it which serializer to retrieve.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I added a builder, it's 35°C here though so it's probably not correct. Just wanted to get some feedback. I left the getDefaultExclusionStrategy method in the Serializer, because I think it should still use grouping by default no matter what, and I think it should be easy to override by extending it.

@schmittjoh
Copy link
Owner

Hehe, no problem, I will take a look; we have a rain period here ;)

Would you mind submitting a PR just with the group changes? That part is really uncontroversial, e.g. GroupsExclusionStrategy changes plus related test changes.

@Seldaek
Copy link
Contributor Author

Seldaek commented Jun 29, 2012

I'd rather keep it all in one and work on getting it through ASAP if you
give me feedback. Maybe stop by on irc so we can discuss it.

@schmittjoh
Copy link
Owner

Basically, I'd like to move the builder functionality of the serializer into the builder object. We could also allow people to configure several different serializers beforehand:

jms_serializer:
    serializers:
        foo:
            groups: [a,b,c]
            version: 1.2
            exclusion_strategy: some_id
$container->get('foo_serializer') // gets the configured serializer
$container->get('jms_serializer.builder')->setGroups(array('foo'))->getSerializer() // allows to build one dynamically at runtime
$container->get('jms_serializer.builder')->loadConfig('foo')->setVersion('1.0')->getSerializer() // creates a new serializer using the config of the "foo" serializer as a base

The public API of the serializer would change to only serialize and deserialize with no more setExclusionStrategy etc. methods.

@@ -115,7 +116,14 @@
</call>
<tag name="jms_serializer.serializer" />
</service>
<service id="jms_serializer.serializer_builder" class="%jms_serializer.serializer_builder.class%" public="false">
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe change this to jms_serializer.builder to make it a bit shorter, and it should be prototype-scoped.

@Seldaek
Copy link
Contributor Author

Seldaek commented Jul 2, 2012

@schmittjoh ok I amended the builder commit, please take another look.

@schmittjoh
Copy link
Owner

Yeah, like it.

I have played a bit with the configuration to allow multiple serializers to be configured, but it takes a bit longer than I thought. For reference, I pushed my current wip here:
3d2d560

@Seldaek
Copy link
Contributor Author

Seldaek commented Jul 5, 2012

Alright, do you think it's mergeable as is or do you want to merge only once you have the config stuff done?

@schmittjoh
Copy link
Owner

I'll wait until the config is done as I don't know how much BC is kept, and I'd like to only break BC once.

@wheelsandcogs
Copy link
Contributor

Hi - would this PR allow the scenario where you want different exclusion strategies for serialize and deserialize? I have the following use case:

New User object as JSON data sent to a FOSRestBundle action e.g. POST /users - password should be deserialized so it can be stored. Retrieving the same User e.g. GET /users/1 - should obviously avoid returning the hashed password.

I'm trying to do this with import / export groups, but by default no groups are applied so if you forget to set them by default everything is exposed.

I'm sorry if this is a bit off topic but I thought it'd be worth mentioning before this is set in stone.

@Seldaek
Copy link
Contributor Author

Seldaek commented Jul 11, 2012

Yup this PR should allow this fairly easily. You'd do for example
setGroups(array('Default', 'import')), and it'll take all fields without
a group + those with import, but not export.

@Seldaek
Copy link
Contributor Author

Seldaek commented Aug 18, 2012

@schmittjoh any news on the config front? It'd be nice to get this merged sooner or later because the more we wait the more likely it is that it will impact people.

@schmittjoh
Copy link
Owner

Yeah :/ didn't find time, yet.

@NicolasBadey
Copy link

+1, we also need multiple exclusion policies

@docteurklein
Copy link

+1 too

@mvrhov
Copy link
Contributor

mvrhov commented Oct 5, 2012

+1

@schmittjoh
Copy link
Owner

@Seldaek, I'd like to split this into two separate patches: one for the group changes, and then one for the builder refactoring. The reasoning being, that I'm not yet comfortable with the builder. I can try to extract the parts, but I'm not sure whether I can keep the single commits then, would you mind that?

@NicolasBadey, @docteurklein, @mvrhov, could you explain the use case that you have for multiple exclusion policies? It would help me better understand what we need here.

@Seldaek
Copy link
Contributor Author

Seldaek commented Oct 11, 2012

The thing is the group stuff alone is kinda useless, because as soon as you have an exclusion policy you'll want the groups to remain applied IMO. But if you like to tear the stuff apart from this PR feel free.

@mvrhov
Copy link
Contributor

mvrhov commented Oct 11, 2012

Right now what I'm interested in from this PR is just the same as symfony validator behavior.

@NicolasBadey
Copy link

@schmittjoh for combine Version and Groups on the same porperty

@mvrhov
Copy link
Contributor

mvrhov commented Oct 11, 2012

I don't need what NicolasBadey said ATM, but in the future it would be more than welcome feature.

@Seldaek
Copy link
Contributor Author

Seldaek commented Nov 7, 2012

@schmittjoh FYI I rebased this PR on latest master

@Narretz
Copy link

Narretz commented Jan 25, 2013

How much of that has been implemented? I think Default groups are there, right?

@WishCow
Copy link

WishCow commented Feb 4, 2013

+1, also waiting on this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Serialization Groups Improvements
8 participants