Manipolare dati POST a lavorare con forme Symfony2 quando utilizzato in un'API REST

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

  •  25-10-2019
  •  | 
  •  

Domanda

Sfondo:

Sto scrivendo un'API RESTful su symfony. Voglio che il cliente sia in grado di inviare a un URL utilizzando il tipo di contenuto application / JSON e inviare un oggetto JSON della forma che l'azione di controllo è alla ricerca di.

Im usando una configurazione di controllo piuttosto semplice per questo. Assumiamo per scopi dimostrativi che im cercando di autenticare un semplice combo username password.

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

Ora il problema che ho, e hanno ho provato var_dumping questo fino alle calende greche, è che per quale motivo symfony non vuole prendere il / JSON content-corpo applicazione e l'uso che i dati per popolare il modulo i dati.

Nome modulo: api_apiuser

I campi: nome utente, password

Quale sarebbe il modo migliore per gestire questo tipo di compito. Sono aperto a suggerimenti più a lungo che posso ottenere questo lavoro. Grazie per il vostro tempo con la materia.

È stato utile?

Soluzione 2

Ive ha effettivamente trovato un modo simile per risolvere questo problema, dopo aver controllato se il metodo è post e prima vincolante la richiesta al modulo faccio questo:

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 **/
}

Altri suggerimenti

Youll necessità di accedere alla richiesta corpo RAW e quindi utilizzare json_decode. Youll probabilmente bisogno di cambiare il metodo di bindRequest a qualcosa di simile al seguente:

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 havent davvero pasticciato con SF2 eppure così questo è più indovinare basa sul API, exp. con sf1.x e le cose ive ottenuto dalle presentazioni sul quadro. Potrebbe anche essere meglio fare un metodo completamente diverso, come bindJsonRequest quindi le cose sono un po 'più ordinato.

Sì, che il modulo è in attesa durante legante è una matrice contenente chiavi che corrispondono alle proprietà ApiUser.

Quindi, se si invia una richiesta POST con la stringa:

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

Si dovrà trasformarlo in un array usando json_decode ad esempio:

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

Poi si associa questo array per il modulo utilizzando $form->bind($data);

Il modulo aggiornerà le proprietà ApiUser corrispondenti alle chiavi di matrice (nome utente, password).

Se si sta costruendo un'API JSON RESTful, mi vuoi consigli di automatizzare questo processo utilizzando Serializzatori / trasformatori, come https://github.com/schmittjoh/JMSSerializerBundle/blob/master/Resources/doc/index.rst

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top