Search code examples
jsonsymfonypostfosrestbundle

FOSRest Symfony POST using json


I'm new with the symfony framework. I'm trying to create webservices with FOSRest bundle but I had a problems when I tried to implement the POST method for one entity with json.

Test:

public function testJsonPostNewTesteAction(){
    $this->client->request(
        'POST',
        '/api/teste/new',
        array(),
        array(),
        array(
            'Content-Type' => 'application/json',
            'Accept' => 'application/json'
        ),
        '{"Teste":{"title":"O teu title"}}'
    );
    $response = $this->client->getResponse();
    $this->assertJsonResponse($response, Codes::HTTP_CREATED);
}

Controller:

/**
 *
 * @Config\Route(
 *      "/teste/new",
 *      name="postTestNew"
 * )
 * @Config\Method({"POST"})
 *
 * @param Request $request the request object
 *
 * @return View|Response
 */
public function postNewTeste(Request $request){
    return $this->processFormTest($request);
}

/**
 * Method for create the process form to Advertisements
 *
 * @param Request $request
 *
 * @return mixed
 */
private function processFormTest(Request $request){
    $form = $this->createForm(
        new TesteType(),
        new Teste()
    );
    $form->bind($request);
    //$from->handleRequest($request);
    if ($form->isValid()) {
        $test = $form->getData();
        return $test;
    }
    return View::create($form, Codes::HTTP_BAD_REQUEST);
}

The problem is when I use the handleRequest(), the method isValid() returns false because the form didn't submit. So I try to change the handleRequest to the bind method. In the last case, the method isValid() returns true but the method getData() returns a null object.

I don't know if the problem is the type form class bellow.

Type Form:

/**
 * The constant name to that type
 */
const TYPE_NAME = "Teste";

/**
 * {@inheritdoc}
 */
public function buildForm(FormBuilderInterface $builder, array $options){
    parent::buildForm($builder, $options);
    $builder->add("title", ValidationType::TEXT);
}

/**
 * {@inheritdoc}
 */
public function setDefaultOptions(OptionsResolverInterface $resolver){
    $resolver->setDefaults(
        array(
            'csrf_protection' => false,
            'cascade_validation' => true,
            'data_class' => 'oTeuGato\DatabaseBundle\Entity\Teste'
        )
    );
}

/**
 * Returns the name of this type.
 *
 * @return string The name of this type
 */
public function getName(){
    return AdvertisementType::TYPE_NAME;
}

I need to POST the entity with both ways. Anyone sugest anything for my problem?

Thanks for the patience!


Solution

  • Got the same issue with the form binding, the only way i found to solve it was to set an empty string to the form getName function:

    /**
     * Returns the name of this type.
     *
     * @return string The name of this type
     */
    public function getName(){
        return '';
    }
    

    And i would suggest to use the handleRequest method when you bind your data because the bind method is deprecated:

    private function processFormTest(Request $request){
        $form = $this->createForm(
            new TesteType(),
            new Teste()
        );
    
        $from->handleRequest($request);
    
        if ($form->isValid()) {
            $test = $form->getData();
            return $test;
        }
    
        return View::create($form, Codes::HTTP_BAD_REQUEST);
    }
    

    It looks more like a hack but seems like it's the only way for now: https://github.com/FriendsOfSymfony/FOSRestBundle/issues/585