POST data manipulation for working with Symfony2 forms when used in the REST API

Background:

I am writing a RESTful API in symfony. I want the client to be able to publish the URL using an application like content / json and publish the json object of the form that is looking for the controller action.

I am using a fairly basic controller setup for this. Let's assume for demonstration purposes that they are trying to authenticate a simple combination of username passwords.

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'))); } } } 

Now the problem that I have, and I tried var_dumping this until the cow gets home, is that there is ever a reason why Symfony does not want to use the application / json content body and use this data to populate data forms.

Form Name: api_apiuser

Fields: username, password

What would be the best way to handle this type of task. I am open to suggestions as long as I can get this to work. Thanks for your time with this question.

+6
php symfony
source share
3 answers

Actually, I found a similar way to fix this, AFTER checking if the post method is and before binding the request to the form, I do this:

 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 **/ } 
+5
source share

You need to access the body of the RAW request and then use json_decode. You probably need to change your bindRequest method to the following:

 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); } } 

I really haven't messed up SF2, but this is more guessing based on the API, exp. with sf1.x and things received from presentations on the framework. Perhaps it would be better to make a completely different method, for example bindJsonRequest , so everything is a little neat.

+6
source share

Yes, what the form expects during the binding is an array containing keys that match your ApiUser properties.

So, if you send a POST request with the line:

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

You will need to convert it to an array using json_decode , for example:

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

Then you bind this array to the form using $form->bind($data);

The form will update your ApiUser properties corresponding to the keys of the array (username, password).

If you are creating a RESTful json api, I would advise you to automate this process using serializers / transformers, for example https://github.com/schmittjoh/JMSSerializerBundle/blob/master/Resources/doc/index.rst

+2
source share

All Articles