Как кодировать сущности Doctrine в JSON в приложении Symfony 2.0 AJAX? - PullRequest
87 голосов
/ 15 июля 2011

Я занимаюсь разработкой игрового приложения и использую Symfony 2.0. У меня много AJAX-запросов к бэкэнду. И больше ответов - это преобразование сущности в JSON. Например:

class DefaultController extends Controller
{           
    public function launchAction()
    {   
        $user = $this->getDoctrine()
                     ->getRepository('UserBundle:User')                
                     ->find($id);

        // encode user to json format
        $userDataAsJson = $this->encodeUserDataToJson($user);
        return array(
            'userDataAsJson' => $userDataAsJson
        );            
    }

    private function encodeUserDataToJson(User $user)
    {
        $userData = array(
            'id' => $user->getId(),
            'profile' => array(
                'nickname' => $user->getProfile()->getNickname()
            )
        );

        $jsonEncoder = new JsonEncoder();        
        return $jsonEncoder->encode($userData, $format = 'json');
    }
}

И все мои контроллеры делают одно и то же: получают сущность и кодируют некоторые из ее полей в JSON. Я знаю, что могу использовать нормализаторы и кодировать все права. Но что, если у сущности есть циклические ссылки на другую сущность? Или граф сущностей очень большой? У вас есть какие-нибудь предложения?

Я думаю о некоторой схеме кодирования для сущностей ... или использовании NormalizableInterface, чтобы избежать зацикливания ..,

Ответы [ 12 ]

3 голосов
/ 13 сентября 2016

Когда вам нужно создать множество конечных точек API REST в Symfony, лучше всего использовать следующий стек пакетов:

  1. JMSSerializerBundle для сериализации сущностей Doctrine
  2. FOSRestBundle связка для прослушивателя представления ответа.Также он может генерировать определение маршрутов на основе имени контроллера / действия.
  3. NelmioApiDocBundle для автоматического создания онлайн-документации и песочницы (что позволяет тестировать конечную точку без какого-либо внешнего инструмента).

При правильной настройке код вашей сущности будет выглядеть следующим образом:

use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;

/**
 * @ORM\Table(name="company")
 */
class Company
{

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     *
     * @JMS\Expose()
     * @JMS\SerializedName("name")
     * @JMS\Groups({"company_overview"})
     */
    private $name;

    /**
     * @var Campaign[]
     *
     * @ORM\OneToMany(targetEntity="Campaign", mappedBy="company")
     * 
     * @JMS\Expose()
     * @JMS\SerializedName("campaigns")
     * @JMS\Groups({"campaign_overview"})
     */
    private $campaigns;
}

Затем код в контроллере:

use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use FOS\RestBundle\Controller\Annotations\View;

class CompanyController extends Controller
{

    /**
     * Retrieve all companies
     *
     * @View(serializerGroups={"company_overview"})
     * @ApiDoc()
     *
     * @return Company[]
     */
    public function cgetAction()
    {
        return $this->getDoctrine()->getRepository(Company::class)->findAll();
    }
}

Преимущества такой настройки::

  • @ JMS \ Expose () аннотации в сущности можно добавлять к простым полям и к любым типам отношений.Также есть возможность выставить результат выполнения какого-либо метода (для этого используйте аннотацию @JMS \ VirtualProperty ())
  • С помощью групп сериализации мы можем управлять открытыми полями в различных ситуациях.
  • Контроллеры оченьпросто.Метод действия может напрямую возвращать сущность или массив сущностей, и они будут автоматически сериализованы.
  • И @ApiDoc () позволяет проверять конечную точку напрямую из браузера, без какого-либо REST-клиента или кода JavaScript
2 голосов
/ 20 ноября 2016

Теперь вы также можете использовать Doctrine ORM Transformations для преобразования сущностей во вложенные массивы скаляров и обратно

...