Манипулирование данными поста для работы с формами Symfony2 при использовании в API REST

StackOverflow https://stackoverflow.com/questions/9304214

  •  25-10-2019
  •  | 
  •  

Вопрос

Фон:

Я пишу спокойный API на Symfony. Я хочу, чтобы клиент имел возможность публиковать URL -адрес, используя приложение типа контента/JSON и разместил объект JSON Form, который ищет действие контроллера.

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

public function loginAction( Request $request )
{
    $user = new ApiUser();
    $form = $this->createForm(new ApiUserType(), $user);
    if ( "POST" == $request->getMethod() ) {
        $form->bindRequest($request);
        if ( $form->isValid() ) {
            $em = $this->getDoctrine()->getEntityManager();
            $repo = $this->getDoctrine()->getRepository('ApiBundle:ApiUser');
            $userData = $repo->findOneByUsername($user->getUsername());
            if ( is_object($userData) ) {
                /** do stuff for authenticating **/
            }
            else{
                return new Response(json_encode(array('error'=>'no user by that username found')));
            }
        else{
            return new Response(json_encode(array('error'=>'invalid form')));
        }
    }
}

Теперь проблема, с которой у меня есть, и я пробовал var_dumping это до тех пор, пока коровы не вернутся домой, заключается в том, что из-за какой-либо причины Symfony не хочет принимать приложение/JSON Content-Body и использовать эти данные для заполнения данных формы.

Имя формы: API_APIUSER

Поля: имя пользователя, пароль

Что будет лучшим способом выполнения этого типа задачи. Я открыт для предложений, пока я могу работать. Спасибо за ваше время с этим вопросом.

Это было полезно?

Решение 2

Я на самом деле нашел аналогичный способ исправить это, после проверки, является ли метод, и перед тем, как привязать запрос с формой, я делаю это:

if ( "POST" === $request->getMethod() ) {
    if (0 === strpos($request->headers->get('Content-Type'), 'application/json')){
        $data = json_decode($request->getContent(), true);
        $request->request->replace(is_array($data) ? $data : array());
    }
    $form->bindRequest($request);
    /** Rest of logic **/
}

Другие советы

Вам нужно получить доступ к корпусу запроса RAW, а затем использовать json_decode. Вам, вероятно, нужно изменить свой bindRequest метод к чему -то вроде следующего:

public function bindRequest(Request $request) 
{
       if($request->getFormat() == 'json') {
           $data = json_decode($request->getContent());
           return $this->bind($data);
        } else {
           // your standard logic for pulling data form a Request object
           return parent::bind($request);
        }
}

Я еще не перепутал с SF2, так что это больше догадывает, основанный на API, Exp. с SF1.x и вещами я получил из презентаций на рамках. Также может быть лучше сделать совершенно другой метод, как bindJsonRequest Так что все немного более аккуратно.

Да, то, чего ждет форма во время привязки, - это массив, содержащий ключи, которые соответствуют вашим свойствам Apiuser.

Так что, если вы отправляете запрос сообщения со строкой:

{ username: 'user', password: 'pass' }

Вам придется преобразовать его в массив, используя json_decode Например:

$data = json_decode($request->getContent()); // $request->request->get('json_param_name');

Затем вы связываете этот массив с формой, используя $form->bind($data);

Форма будет обновлять ваши свойства Apiuser, соответствующие ключам массива (имя пользователя, пароль).

Если вы строите Restful JSON API, я бы посоветовал вам автоматизировать этот процесс, используя сериалы/трансформаторы, например https://github.com/schmittjoh/jmsserializerbundle/blob/master/resources/doc/index.rst

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top