nilportugues / symfony-jsonapi

JSON API Transformer Bundle for Symfony 2 and Symfony 3
http://nilportugues.com
MIT License
115 stars 19 forks source link

Several questions about working with Doctrine relations #27

Open trogwarz opened 7 years ago

trogwarz commented 7 years ago

Hello.

How to use it with Doctrine relations (both types: Associations and Embedded)? I have several problems with this feature.

src/FirstBundle/Entity/First.php

<?php

namespace FirstBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use SecondBundle\Entity\Second;

/**
 * @ORM\Entity(repositoryClass="FirstBundle\Repository\First")
 */
class First
{
    /** @ORM\Column(type="datetime") */
    private $created_at;
    /** @ORM\ManyToOne(targetEntity="SecondBundle\Entity\Second", fetch="EAGER") */
    private $second;

    public function getCreatedAt() : \DateTime { return $this->created_at; }
    public function getSecond()    : Second    { return $this->second; }
}

src/FirstBundle/Entity/Embeddable/Contact.php

<?php

namespace FirstBundle\Entity\Embeddable;

use Doctrine\ORM\Mapping as ORM;

/** @ORM\Embeddable */
class Contact
{
    /** @ORM\Column(type="string", length=190) */
    private $city;
    public function getCity() : string { return $this->city; }
}

src/SecondBundle/Entity/Second.php

<?php

namespace SecondBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="SecondBundle\Repository\Second")
 */
class Second
{
}

src/FirstBundle/Resources/config/mapping/first.yml

mapping:
    class: FirstBundle\Entity\First
    id_properties:
        - id
    hide_properties:
        - password
    urls:
        self: first_get_all
    relationships:
        second:
            self: we_dont_need_this

src/FirstBundle/Resources/config/mapping/contact.yml

mapping:
    class: FirstBundle\Entity\Embeddable\Contact
    id_properties: []
    hide_properties: []
    urls:
        self: we_dont_need_this

src/SecondBundle/Resources/config/mapping/second.yml

mapping:
    class: SecondBundle\Entity\Second
    id_properties:
        - id
    hide_properties:
        - password
    urls:
        self: second_get_all

After using this project like this

src/FirstBundle/Controller/First.php

<?php

namespace FirstBundle\Controller;

use NilPortugues\Api\JsonApi\JsonApiSerializer;
use NilPortugues\Symfony\JsonApiBundle\Serializer\JsonApiResponseTrait;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class First extends Controller
{
    use JsonApiResponseTrait;

    /** @var \FirstBundle\Repository\First */
    private $repository;
    /** @var JsonApiSerializer */
    private $serializer;

    public function getAllAction(ParamFetcher $paramFetcher) : Response
    {
        $all = $this->repository->findBy(
            $paramFetcher->get('search') ?? []
            , $paramFetcher->get('order') ?? []
            , $paramFetcher->get('limit')
            , $paramFetcher->get('offset')
        );

        return $this->response($this->serializer->serialize($all));
    }
}

I get very strange response:

{
    "data": [
        {
            "attributes": {
                "created_at": {
                    "date": "2016-11-15 12:52:55.000000",
                    "timezone": "Etc/UTC",
                    "timezone_type": 3
                },
                "id": 1905572758,
            },
            "id": "1905572758",
            "relationships": {
                "contact": {
                    "data": {
                        "id": "",
                        "type": "contact"
                    }
                },
                "second": {
                    "data": {
                        "id": "1819094130",
                        "type": "second"
                    }
                }
            },
            "type": "first"
        }
    ],
    "included": [
        {
            "attributes": {
                "login": "login1",
                "password": "$2y$10$m7flUsxQoXxFIxQbSTdqsejsU2Pa9BF.Zy9JNejm/vQSSzun/w8ze",
                "registered_at": {
                    "date": "2016-11-15 10:05:03.000000",
                    "timezone": "Etc/UTC",
                    "timezone_type": 3
                }
            },
            "id": "1411924520",
            "type": "second"
        },
        {
            "attributes": {
                "login": "f12",
                "password": "$2y$10$kxxKWMt0WPYtHB.BvieatewTb69sR0R/geiIU3kq7Xy6XXuVlrpG.",
                "registered_at": {
                    "date": "2016-11-15 10:58:26.000000",
                    "timezone": "Etc/UTC",
                    "timezone_type": 3
                }
            },
            "id": "1819094130",
            "type": "second"
        }
    ],
    "jsonapi": {
        "version": "1.0"
    }
}

Questions:

  1. How to include Second entity as relationship with First entity? What i'm doin wrong? Connected with #20 i think but there is no solution provided for me.
  2. WTF is with \DateTime and created_at field? How to format this as string? Connected with #21 but not working for me )-:
  3. Why embeddable entity Contact has id field? Don't need this and doesn't have. It has stored just as contact_city field in first table. No PK exists.
  4. Why embeddable entity Contact don't have city field?
  5. Why id for First is string instead of integer (but it is in attributes).
  6. If i remove EAGER loading of relation then i got error Closures are not supported in Serializer – how to fix this?
  7. Why hide_properties is ignored for Second entity? Password must be excluded.

Thank you for your help.