Сериализация тела POST-запроса в массив с помощью FOSRestBundle

Я пытаюсь сделать веб-сервис Rest, используя Symfony 3 и FOSRestBundle.
Я пришел из источника Spring + Jackson, поэтому я пытаюсь сделать так, чтобы вы могли передавать объекты в контроллеры как тело запроса, которое становится параметрами функции, и возвращать объекты, которые сериализованы в json, пока мне удалось заставить его работать на все кроме массивов.
Это мой код:

конфигурация:

#FOSRestBundle
fos_rest:
    param_fetcher_listener: true
    body_listener: 
        enabled: true
        decoders:
            json: fos_rest.decoder.json
    format_listener:
        rules:
            - { path: ^/, priorities: [ json ], fallback_format: json, prefer_extension: true }

    body_converter:
        enabled: true
        #validate: true

    view:
        mime_types:
            json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1']
        view_response_listener: 'force'
        formats:
            xml:  false
            json: true
        templating_formats:
            html: true

    exception:
        codes:
            'Symfony\Component\Routing\Exception\ResourceNotFoundException': 404
            'Doctrine\ORM\OptimisticLockException': HTTP_CONFLICT
        messages:
            'Symfony\Component\Routing\Exception\ResourceNotFoundException': true
    allowed_methods_listener: true
    access_denied_listener:
        json: true

Это контроллер

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use JMS\DiExtraBundle\Annotation\Inject;
use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\View;
use FOS\RestBundle\Controller\FOSRestController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;

class DefaultController extends FOSRestController {

    /**
     * @Post("/rest", name="rest_test")
     * @ParamConverter("myArr", converter="fos_rest.request_body")
     * @View
     * @param Request $request
     */
    public function restAction(Request $request, array $myArr) {
        return $myArr;
    }
}

Когда я пытаюсь позвонить с моего клиента отдыха (положить [1, 2] как тело запроса) я получаю эту ошибку:

{
  "code": 500,
  "message": "Converter 'fos_rest.request_body' does not support conversion of parameter 'myArr'."
}

Если я поверну myArr в объект (то есть я меняю его тип с array в MyObject, содержащий number переменная myVar) и отправлять данные, отражающие структуру этого объекта (например, {"myVar": 2}) он работает нормально, но не работает с массивом.

2 ответа

Решение

После нескольких дней игры с кодом и этого приятного разговора с одним из сотрудников FoS https://github.com/FriendsOfSymfony/FOSRestBundle/issues/1582 я обнаружил, что, если вы используете JMS Serializer Bundle (который, я думаю, у всех есть) можно просто написать array в поле класса преобразователя параметров, и он будет десериализовать его в массив. Я должен был попробовать это раньше, я думаю

@ParamConverter("myarr", class="array", converter="fos_rest.request_body")

Он может даже десериализовать массивы объектов (если они одного класса, я думаю)

@ParamConverter("myarr", class="array<Namespace/Class>", converter="fos_rest.request_body")

ОБНОВЛЕНИЕ Я обновляю этот вопрос, так как я перестал использовать JMS Serializer и начал использовать Symfony Serializer, который имеет другой синтаксис для массивов объектов:

@ParamConverter("myarr", class="Namespace/Class[]", converter="fos_rest.request_body")

Синтаксис нормальных массивов остается неизменным

Цель преобразователя тела FOS Rest состоит в заполнении объектов, а не массивов. Вы можете попробовать реализовать свой собственный конвертер параметров ( см. Эту документацию), но я действительно не уверен, что вы можете достичь того, чего хотите.

Во всяком случае, работа с объектами не будет чище? Это позволит вам быть уверенным, что получаемые вами данные соответствуют ожидаемым, использовать проверки и т. Д.

Другие вопросы по тегам