Skip to content

Add a filter for serialization groups #1111

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

Closed

Conversation

meyerbaptiste
Copy link
Member

@meyerbaptiste meyerbaptiste commented May 10, 2017

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #1082
License MIT
Doc PR N/A

@meyerbaptiste meyerbaptiste force-pushed the add_group_filter branch 3 times, most recently from 1af71a4 to 9694e58 Compare May 10, 2017 15:56
*
* @author Baptiste Meyer <[email protected]>
*/
class GroupFilter implements FilterInterface
Copy link
Member

Choose a reason for hiding this comment

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

final

Copy link
Member Author

@meyerbaptiste meyerbaptiste May 11, 2017

Choose a reason for hiding this comment

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

I followed the same standards as ORM filters: not final + protected methods/attributes.

Copy link
Member Author

Choose a reason for hiding this comment

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

So @dunglas, should we keep consistency with ORM filters or should I follow your requested changes?

Copy link
Member

Choose a reason for hiding this comment

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

ORM filters support only the array syntax. So, same for this new one.

Copy link
Member Author

Choose a reason for hiding this comment

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

No, I talk about final + protected @dunglas 😋

*/
class GroupFilter implements FilterInterface
{
protected $overrideDefaultGroups;
Copy link
Member

Choose a reason for hiding this comment

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

private

*/
public function apply(Request $request, bool $normalization, array $attributes, array &$context)
{
if (empty($groups = $this->extractGroups($request))) {
Copy link
Member

Choose a reason for hiding this comment

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

empty is useless.

return;
}

if (!$this->overrideDefaultGroups && !empty($context['groups'])) {
Copy link
Member

Choose a reason for hiding this comment

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

Same here

*
* @return array
*/
protected function extractGroups(Request $request): array
Copy link
Member

Choose a reason for hiding this comment

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

private

$groups = [];

if (null !== $groupsParameter = $request->query->get($this->parameterName)) {
if (is_string($groupsParameter)) {
Copy link
Member

Choose a reason for hiding this comment

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

Why supporting both syntax? We only support the second one in other filters.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think we should explode or do any transformation on query parameters. Just let symfony do the work here.

I'd propose:

$groups = $request->query->get($this->parameterName);

This method can then be removed as this one line should be enough.

Copy link
Member Author

@meyerbaptiste meyerbaptiste May 11, 2017

Choose a reason for hiding this comment

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

I followed what you described in your issue: ?groups=foo,bar,baz and I added the array syntax. So... should I implement the issue syntax or array syntax or both?

Copy link
Member

Choose a reason for hiding this comment

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

After a second though, I was wrong :) We should just support the array syntax, just like for other fields (consistency...).

$resourceFilters = $resourceMetadata->getItemOperationAttribute($attributes['item_operation_name'], 'filters', [], true);
}

if (empty($resourceFilters)) {
Copy link
Member

Choose a reason for hiding this comment

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

empty is useless

@meyerbaptiste meyerbaptiste force-pushed the add_group_filter branch 3 times, most recently from 9caf397 to abe708b Compare May 11, 2017 12:41
return;
}

if (!$this->overrideDefaultGroups && isset($context['groups']) && is_array($context['groups'])) {
Copy link
Member Author

@meyerbaptiste meyerbaptiste May 11, 2017

Choose a reason for hiding this comment

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

About is_array($context['groups']), I'm not really sure how we should handle the case where $context['groups'] exists and is not an array:

  • cast $context['groups'] to array and apply the filter
  • do not apply the filter when $overrideDefaultGroups is true or false (so in all cases)
  • apply the filter when $overrideDefaultGroups is true
  • apply the filter and overwrite the value of $context['groups'] in all cases (current behavior)

WDYT?

Copy link
Member

Choose a reason for hiding this comment

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

What is $context['groups'] if not an array? I think we should cast is as one.

Copy link
Member Author

@meyerbaptiste meyerbaptiste May 12, 2017

Choose a reason for hiding this comment

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

What is $context['groups'] if not an array?

I don't know, it's just an assumption!

Copy link
Member

Choose a reason for hiding this comment

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

Should be a string, therefore we could cast it as array.

*
* @author Baptiste Meyer <[email protected]>
*/
final class SerializerContextBuilderFilter implements SerializerContextBuilderInterface
Copy link
Member

Choose a reason for hiding this comment

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

SerializerFilterContextBuilder?

@teohhanhui
Copy link
Contributor

To restate what I've raised in #1082 (comment), I think we should not introduce misfeatures like this...

@teohhanhui
Copy link
Contributor

teohhanhui commented May 15, 2017

If we are to have a "property group" filter, then the "property groups" MUST be exposed as resources. That's the way to keep things as hypermedia.

We need to always keep these principles in mind, as we claim that API Platform is a hypermedia framework / library. 😄

Copy link
Contributor

@teohhanhui teohhanhui left a comment

Choose a reason for hiding this comment

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

Please take #1111 (comment) into account. Which also means this needs to be generalized into a "property groups" filter, not a "serializer groups" filter (implementation detail).

@dunglas
Copy link
Member

dunglas commented May 17, 2017

@teohhanhui I'm not sure to get exactly what you have in mind? Can you give us some details?
For me, this filter is a purely technical feature to save bandwidth. It's one of the most wanted feature by our customers and I often see projects having this kind of filters (as custom filters).

It's also a 100% optin filter.

@dunglas
Copy link
Member

dunglas commented May 17, 2017

Regarding the implementation details leak, this is not true. As stated just before, filter is 100% optional and must be enabled manually by the developper. When doing this, you know that the groups will be exposed publicly, and you need to take care of this. It's the developper responsibility.

@meyerbaptiste meyerbaptiste force-pushed the add_group_filter branch 3 times, most recently from 61b97bb to cb4d458 Compare May 18, 2017 09:19
@teohhanhui
Copy link
Contributor

Yeah, I guess it must be very hard to expose the property groups as resources.

But I wish we could change "groups" to "property_groups"?

@teohhanhui
Copy link
Contributor

When I said it's a leak of implementation detail, I meant that these groups are not defined anywhere. They are not exposed as resources, they are not in the Swagger doc. So they're magical as far as the client is concerned... Out-of-band information which is a big nono.

@dunglas
Copy link
Member

dunglas commented May 18, 2017

I agree about the out of band information. However this is not the case the fields filter, so it should be privileged when developing hypermedia API.

About the name, I prefer groups (shorter is better), but it should be configurable, and it is :)

@meyerbaptiste meyerbaptiste force-pushed the add_group_filter branch 4 times, most recently from b2df66a to 3d71742 Compare May 22, 2017 13:26
@meyerbaptiste meyerbaptiste deleted the add_group_filter branch May 23, 2017 08:42
@meyerbaptiste
Copy link
Member Author

Merged with #1123, see e3c17c8.

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

Successfully merging this pull request may close these issues.

4 participants