Open mgiustiniani opened 10 years ago
With Symfony2 Project and FosRestBundle i can't use Hateoas Collection because these models havent' groups serialization.
i resolve this bug (limitation is more correctly) with override configuration (in Symfony2 Project):
jms_serializer:
metadata:
directories:
Hateoas:
namespace_prefix: "Hateoas\\Representation"
path: "%kernel.root_dir%/serializer/Hateoas/"
PaginatedRepresentation.yml:
Hateoas\Representation\PaginatedRepresentation:
relations:
- rel: self
href:
route: expr(object.getRoute())
parameters:
parameters:
page: expr(object.getPage())
_format: json
absolute: expr(object.isAbsolute())
exclusion:
groups: [list, detail]
- rel: first
href:
route: expr(object.getRoute())
parameters:
page: 1
_format: json
absolute: expr(object.isAbsolute())
exclusion:
groups: [list, detail]
- rel: last
href:
route: expr(object.getRoute())
parameters:
page: expr(object.getPages())
_format: json
absolute: expr(object.isAbsolute())
exclusion:
groups: [list, detail]
exclude_if: expr(object.getPages() === null)
- rel: next
href:
route: expr(object.getRoute())
parameters:
page: expr(object.getPage()+1)
_format: json
absolute: expr(object.isAbsolute())
exclusion:
groups: [list, detail]
exclude_if: expr(object.getPages() !== null && (object.getPage() + 1) > object.getPages())
- rel: previous
href:
route: expr(object.getRoute())
parameters:
page: expr(object.getPage()-1)
_format: json
absolute: expr(object.isAbsolute())
exclusion:
groups: [list, detail]
exclude_if: expr((object.getPage() - 1) < 1)
properties:
page:
groups: [list, detail]
limit:
groups: [list, detail]
pages:
groups: [list, detail]
RouteAwareRepresentation.yml
Hateoas\Representation\RouteAwareRepresentation:
properties:
inline:
groups: [list, detail]
inline: true
I just came a similar issue to this also which may be related. The '_links' (and probably '_embedded') are not included in the serialization i think because the event subscriber sends the custom context into the InlineDeferrer::handleItems method.
$hateoas = HateoasBuilder::create()->build();
$json = $hateoas->serialize($object, 'json', SerializationContext::create()->setGroups(['public']));
Quick messing about seems to solve the issue by adding 'Default' into the groups array to include non-grouped object attributes.
Same issue, serializer groups doesn't works with CollectionRepresentation :/
Yep, I'm also hitting this one. IMO all represenations should have "groups" e.g pager pager, collection, collection ...
i added a PR in jms serializer for risolve this issue, after this we can create PR for resolve links object serialization
@mgiustiniani: There is no need for that. All that has to be done is add groups into all default Hateoas configurations. e.g Paginated representation configuration gets put into hateoas_paginated
group, route aware into hateoas_route
.
Now this will break BC, but IMO there is no way around it as this was broken from the start.
@mvrhov my PR in jms serializer resolve limit for this library and for other libraries (ie: with https://github.com/djlambert/doctrine2-spatial, spatials objects can't serialized with groups)
When using groups with Hateoas, I specify the Default (which will keep all the Hateoas representations properties) group along with my custom groups.
What we could do is add an "Hateoas" group.
You would then specify the Hateoas group along with your custom groups.
EDIT: Adding an Hateoas seems harder than expected.
Default works for me also so far.
@willdurand why did you close this? Usually You don't want a Default group as this means that you have to push a lot of your own property declarations into another group.
Well, it looked like a decent answer to me... Let's reopen it, but I don't have any solution..
@mvrhov i've same problem but i haven't considered this functionality:
/**
* @Rest\View(serializerGroups={"list", "Default"})
**/
public function cgetNotesAction(){
// some stuff here
}
I can't test now this solution.
This could be related to #164.
I don't see this as an issue or limitation.
If you are using serialization groups and want to expose properties generated by PaginatedRepresentation or CollectionRepresentation then you have three options:
@mvrhov https://github.com/willdurand/Hateoas/issues/141#issuecomment-38796022
Yes, we could add groups to the hateoas built in representations. However even though all the properties/links will have a hateoas_xxx
group, they should also keep the Default
group.
I got this working with v2.5.0
with the following code (thanks to @mgiustiniani, i modified it only a little)
https://gist.github.com/dsbaars/56be85286ebf4f89e4d4
Unfortunately i can't get the per item links working. I can't use the Default serialziation group in some cases. If someone can help me with the metadata configuration to get this working, it'll save me the time creating my own Annotation Listener which is a little overkill to solve this ;)
Grouping not work for me too.
+1
+1
Maybe this design/limitation should be documented, can I submit a documentation PR for this?
@kipit yes!
@dsbaars : I answered to your gist, I past the missing file here for thoses who won't follow your link (they should because your solution works) :
Hateoas\Representation\AbstractSegmentedRepresentation:
properties:
limit:
expose: true
groups: [Hateoas]
total:
expose: true
groups: [Hateoas]
Any news on this? I don't see any clear solution on how to solve this issue
@jcornide dsbaars's comment lead to a gist that let you manually adress this problem . I needed to add an extra conf. that I added in a comment of this gist.
I can't figure it out why not these both classes (PaginatedRepresentation and CollectionRepresentation) can't hold the missing "groups"-attribute inside the annotations.
Why should I override the serialization configuration as proposed at the gist?
Maybe someone can me explain this situtation? I think I misunterstood something. ;)
I tried creating separate config files as @mgiustiniani suggested, but the serializer still seems to use the annotations of the PaginatedRepresentation
and related classes.
Since I'm using Symfony 4.1, my config is a little different:
metadata:
directories:
hateoas:
namespace_prefix: "Hateoas\\Representation"
path: '%kernel.project_dir%/config/serializer/hateoas'
EDIT:
I was using .yaml instead of .yml for the file extensions. Changing them fixed it :)
Hi everyone,
I've spent some hours on this issue too. I tried all workarounds mentioned here by overriding the exclusion rules via metadata, but I wasn't able to get it up and running.
Then I found that you can override groups of deeper branches with the JMS library. But that didn't seem to work until I noticed issue #260 where it does mention that it works.
The thing is, I didn't quite understand how that override worked. I thought you had to use the variable name inline
from the RouteAwareRepresentation
class, but it's actually the 'rel' name you're passing as argument when building your collection.
See following example:
<?php
use JMS\Serializer\Annotation as Serializer;
/**
* @Serializer\ExclusionPolicy("all")
*/
final class User {
/**
* @Serializer\Expose()
*/
private $id;
/**
* @Serializer\Expose()
* @Serializer\Groups({"sensitive"})
*/
private $name;
}
First you define the representation.
$collection = new OffsetRepresentation(
new CollectionRepresentation(
$users,
'my_user_rel'
),
'some_route'
);
The problem we currently have, if we want to return the collection of users with only the sensitive data, is that following will not work, because the collection does not comply with the group exclusion rule.
$jms->serialize($collection, 'json', $jms->serialize($collection, 'json', SerializationContext::create()->setGroups(['sensitive']));
Instead, you should tell the exclusion rule to only be applied on the "User" object itself. This can be done with the "overriding" method of JMS, but, and this is important as I didn't get it immediately, you must use the name you gave to the 'rel' argument. Notice the strange name I gave my_user_rel, this was intentionally for the sake of the example :)
Doing following should solve the groups issue once and for all
$jms->serialize($collection, 'json', SerializationContext::create()->setGroups([
'Default',
'my_user_rel' => [
'sensitive'
]
]))
If, for example, you want to also include the other fields then you simply add Default also:
$jms->serialize($collection, 'json', SerializationContext::create()->setGroups([
'Default',
'my_user_rel' => [
'Default',
'sensitive'
]
]))
If we are not going to come with an alternative solution, maybe this could be added to the documentation somewhere? (/cc @willdurand )
Anyway, I hope this will help future devs to not waste hours on this like me ^^
Cheers
Youhou tonivdv !!! It works perfectly ! I spent 4 hours looking for a solution! So we can do it with Annotations if we work with FOSRest:
Hi I did the same but i am getting empty response.
$serializer = HateoasBuilder::create() ->setUrlGenerator(null, $queryStringUrlGenerator) ->addMetadataDir(DIR . '/../Resources/config/serializer/Hateoas', 'Hateoas\Representation')->build() $collection = new CollectionRepresentation($users); $json = $serializer->serialize($collection, 'json', SerializationContext::create()->setGroups(['users']));
Metadata FileName: CollectionRepresentation.yml
Hateoas\Representation\CollectionRepresentation: exclusion_policy: none properties: id: type: integer groups: ['users']
Any suggestions please? @willdurand
Can you provide a test or something a bit more detailled?