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

Serialization groups for self-referenced doctrine entity #244

Closed
blt909 opened this issue Aug 26, 2015 · 7 comments
Closed

Serialization groups for self-referenced doctrine entity #244

blt909 opened this issue Aug 26, 2015 · 7 comments

Comments

@blt909
Copy link

blt909 commented Aug 26, 2015

Hello,

I wonder if it is possible to embed a relation from an entity to the same entity and have different properties shown on GET operation.
I need to get a full user with related users having fewer properties in.

The sample class :

/**
 * @ORM\Entity
 * @ORM\Table(name="user")
 */
class User
{
    /**
     * @Groups({"userN", "fewerN",})
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @Groups({"userN", "userD"})
     * @Assert\Email
     */
    protected $email;

/**
     * @Groups({"userN","userD", "fewerN"})
     * @ORM\Column(type="string", unique=false, nullable=true)
     */
    private $pseudo;

    /**
     * @Groups({"userN", "fewerN"})
     * @Gedmo\Slug(fields={"pseudo"}, unique=true)
     * @ORM\Column(type="string",length=255, unique=true)
     */
    private $slug;

    /**
     * @Groups({"userN","userD"})
     * @ORM\Column(name="mobile", type="string", nullable=true)
     * @Assert\Type(type="string")
     */
    private $mobile;

    /**
     * @Groups({"userN","userD"})
     * @ORM\Column(name="gender", type="string", nullable=true)
     * @Assert\Type(type="string")
     */
    private $gender;

   /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="myFriends")
     **/
    private $friendsWithMe;


    /**
     * @Groups({"fewerN","userD"})
     * @ORM\ManyToMany(targetEntity="User", inversedBy="friendsWithMe")
     * @ORM\JoinTable(name="friends",
     *      joinColumns={@ORM\JoinColumn(name="friend_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="friendwith_id", referencedColumnName="id")}
     *      )
     **/
    private $myFriends;

}

The ressource definition I thinked about :

resource.user:
        parent:         "api.resource"
        arguments:      [ "AppBundle\\Entity\\User" ]
        calls:
            -   method:         "initNormalizationContext"
                arguments:      [ { groups: [ "userN", "fewerN" ] } ]
            -   method:         "initDenormalizationContext"
                arguments:      [ { groups: [ "userD"] } ]
        tags:      [ { name: "api.resource" } ]

The wanted result :

{
  "@context": "/api/contexts/User",
  "@id": "/api/users/3",
  "@type": "User",
  "email": "someone@fxlan.com",
  "pseudo": "someone",
  "slug": "someone",
  "mobile": "+33666666666",
  "gender": "male",
  "myFriends": [
    {
      "@id": "/api/users/2",
      "@type": "User",
      "pseudo": "somebody",
      "slug": "somebody",
      "myFriends": []
    }
  ]
}

The actual result :

{
  "@context": "/api/contexts/User",
  "@id": "/api/users/3",
  "@type": "User",
  "email": "someone@fxlan.com",
  "pseudo": "someone",
  "slug": "someone",
  "mobile": "+33666666666",
  "gender": "male",
  "myFriends": [
    {
      "@id": "/api/users/2",
      "@type": "User",
      "email": "somebody@fxlan.com",
      "pseudo": "somebody",
      "slug": "somebody",
      "mobile": "+33666666666",
      "gender": "male",
      "myFriends": []
    }
  ]
}

I think there is something I don't understand, but maybe there's a known recipe for that use case.

Thank you.

@dunglas
Copy link
Member

dunglas commented Aug 26, 2015

Hello,

The only solution for now for such case is creating a custom normalizer.

@blt909
Copy link
Author

blt909 commented Aug 27, 2015

Ok I'll try that.
Is there any API bundle doc ressource regarding registering a custom normalizer that I missed?
Or perhaps it is the standard symfony procedure?

@theofidry
Copy link
Contributor

You can find examples of custom normalizer in the bundle:

But otherwise it's pretty much the Symfony procedure: Symfony Serializer Component.

@blt909
Copy link
Author

blt909 commented Aug 27, 2015

@theofidry thanks

@teohhanhui
Copy link
Contributor

@dunglas Would be good if we can hook into the metadata process to modify things (e.g. add parent and children in the form of IRI for self-referencing relation)? Will it be possible once your rewrite to use the Symfony PropertyInfo component is complete?

@teohhanhui
Copy link
Contributor

I suppose it's already possible with a custom metadata loader (implementing Dunglas\ApiBundle\Mapping\Loader\LoaderInterface).

leesiongchan pushed a commit to leesiongchan/api-platform-core that referenced this issue Mar 6, 2018
leesiongchan pushed a commit to leesiongchan/api-platform-core that referenced this issue Mar 6, 2018
@vipulw2011
Copy link

@dunglas I am also facing the same issue and require exactly same. How do I do it ? Is there any example for it ?

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

No branches or pull requests

5 participants