2016-09-29 3 views
1

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

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

#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'." 
} 

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

ответ

2

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

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

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

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

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

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

+0

Я всегда могу создать объект с массив внутри я думаю (еще не пробовал). Но есть ситуации, в которых мне приходится посылать, например, массив идентификаторов, чтобы сообщить бэкэнду делать операции над набором элементов. – valepu

+0

Возможно, это ваш дизайн REST, который не является правильным? REST не предназначен для работы с несколькими ресурсами с одним запросом. Если вам действительно нужно это сделать, я думаю, вам придется делать это вручную, потому что FOS REST не предназначен для этого. :/ – Boulzy

+0

Документация fosrestbundle даже говорит, что вы можете использовать автоматически созданный метод PATCH (еще не пробовал), чтобы частично обновить подмножество ресурсов http://symfony.com/doc/current/bundles/FOSRestBundle/5-automatic -route-generation_single-restful-controller.html, все же это был всего лишь пример ... Я довольно уверен, что есть много вариантов использования, где вам может понадобиться сдать массив в вызове REST. Кроме того, Spring + Jackson позволяет отправлять массив (любого вида) в качестве тела запроса – valepu

 Смежные вопросы

  • Нет связанных вопросов^_^