IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Webservice REST - Trop de requêtes [2.x]


Sujet :

Symfony PHP

  1. #1
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 14
    Points : 12
    Points
    12
    Par défaut Webservice REST - Trop de requêtes
    Bonjour,

    je débute dans les webservices avec Symfony et j'ai un problème pour l'export de mes données en JSON.

    En effet j'utilise FOSRESTBundle dont voici un exemple dans l'une de mes méthodes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <?php
    public function listGroupsAction(){
           $em = $this->getDoctrine()->getEntityManager()->getRepository('myGroupingBundle:Group');    
           $groups= $em->findAllGroups();
     
           $view = View::create()  
              ->setStatusCode(200); 
            if ('html' === $this->getRequest()->getRequestFormat()){
                $view->setData(array('groups' => $groups));
            }else{
                $view->setData($groups);  
            }
            $view->setTemplate('myGroupingBundle:group:list.html.twig');
     
            return $this->get('fos_rest.view_handler')->handle($view);  
        }
    Le problème est que j'ai plus de 90 requêtes effectuées car toutes les relations entre mes entités sont chargées... Alors qu'avec la vue twig je n'en ai que 3 car uniquement données que j'ai besoin sont chargées.

    Je ne sais pas comment faire pour limiter aux données que je souhaite. Auriez vous une idée?

  2. #2
    Membre averti

    Inscrit en
    Juin 2008
    Messages
    307
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 307
    Points : 364
    Points
    364
    Par défaut
    Montre nous la requête findAllGroup et la description de tes entitées.

    Au vu de ton problème, ta requête va chercher des objet qui n'ont pas lieu d'êtres récupérés ou effectue pour chaque résultat plusieurs requêtes pour récupérer les entités liées.

    Généralement, ce genre de problème se résout en précisant les jointures à effectuer ainsi que les champs à récupérer.

  3. #3
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 14
    Points : 12
    Points
    12
    Par défaut
    Pour donner plus de détails j'ai trois Bundle :
    - User
    - Group
    - Aid

    User est relié au deux car chacun des Bundles à soit des membres soit un créateur.

    Voici un exemple de requête que je fais, là (lorsque de je demande du JSON) toutes les entités liés à User sont chargées à leur tour, donc leurs groups etc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public function findAllMutualAid() {
            $qb = $this ->createQueryBuilder('m')
                            ->leftJoin('m.tags','t')
                            ->leftJoin('m.user','u')
                            ->addSelect('u') 
                            ->addSelect('t')
                            ->addOrderBy('m.date', 'DESC')
                            ;
     
     
            return  $qb->getQuery()->getResult();
        }

  4. #4
    Membre averti

    Inscrit en
    Juin 2008
    Messages
    307
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 307
    Points : 364
    Points
    364
    Par défaut
    Précise les champs dont tu as besoin dans ta clause select. Ensuite es tu sur que tu as besoin de jointure externe ? Ce type de jointure est utilisée dans des cas bien spécifique (tu veux les données de la table 1 qui on une correspondance dans la table 2 mais également celle qui n'ont pas de correspondance. (null à la place)

    Olivier

  5. #5
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 14
    Points : 12
    Points
    12
    Par défaut
    Je pense avoir besoin des jointures externes oui, car si je prend l'exemple des tags il faut que j'obtienne l'information même si les utilisateurs n'ont pas entré de tags pour celle-ci. Pour utilisateur effectivement il y'en a certainement pas besoin car elles ont toutes un utilisateur.

    Pour le select j'ai modifié ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $this ->createQueryBuilder('m', 'u.lastName', 'u.fisrtName')
    Mais j'ai encore toutes les infomations qui son chargées lorsque je demande en JSON, et dans ma vue quand je regarde la requete du profiler tous les champs sont encore sélectionné alors que j'ai enlevé le "addSelect('u')".

    EDIT: En fait quand j'enlève le add Select Symfony me rajoute de lui-même une requête alors qu'à priori je n'ai besoin de rien d'autre dans ma requête.

    Finalement si je construit ma requête comme ci-dessous j'ai bien que l'id qui vient, le soucis est que je n'ai plus un tableau d'objet. Du coup s'il n'y a pas de solutions ça va m'obliger à doubler toutes mes requêtes pour soit charger l'objet si je souhaite une vue twig, soit une autre requête avec uniquement l'objet et ses relations que je souhaite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    $qb = $this->_em->createQueryBuilder()  
                     ->addSelect('g.id')
                     ->from('ns\GroupingBundle\Entity\Group', 'g')
                     ->where('g.id = :id')
                     ->setParameter('id', $group->getId());
    J'ai aussi vidé mon cache au cas ou.

    Merci de ton aide !

  6. #6
    Membre averti

    Inscrit en
    Juin 2008
    Messages
    307
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 307
    Points : 364
    Points
    364
    Par défaut
    et si tu utilise du dql et un ->createQuery ça marche pareil ?

  7. #7
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 14
    Points : 12
    Points
    12
    Par défaut
    Tout à fait, puisque du coup avec les requêtes précédentes on fait un getQuery() pour obtenir la requête.

    Dans le doute j'ai vérifié mais les symptômes sont les mêmes. Je crois que je vais devoir m'amuser à doubler mes requêtes wouw!

    Merci beaucoup de ton aide en tous cas.

  8. #8
    Membre averti

    Inscrit en
    Juin 2008
    Messages
    307
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 307
    Points : 364
    Points
    364
    Par défaut
    Nan c'est pas normal qu'il te fasse du lazy loading. Normalement comme c'est expliqué ici : http://symfony.com/doc/current/book/...elated-records

    il ne doit faire qu'une requête. Surement que tu l'utilise pas correctement dans ta vu...

  9. #9
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 14
    Points : 12
    Points
    12
    Par défaut
    Béh dis moi si je me trompe mais si j'affiche dans ma vue un élément que ma requête n'a pas chargé alors une requête supplémentaire sera faite?

    Or dans mon cas ce qui pose problème ce n'est pas ma vue mais le JSON qui est demandée en appelant l'URL pour faire l'IHM avec un autre langage (GWT ou autre).

    De ce fait je ne demande pas d'élément. C'est là le problème car du coup tout est renvoyé. Avec ma vue Twig je n'ai pas ce soucis.
    (c'est peut-être pas ce que tu voulais dire? )

    Vraisemblablement ça vient du JMSSerializerBundle, je vais creuser un peu par là en tous cas. Ce serait un comportement normal du Bundle qui chargerais toutes les relations. On peut visiblement passer outre grace aux annotation, notamment @exclude. Je cherche de ce coté là mais pour le moment je n'arrive pas à faire en sorte que ces annotations soient prises en compte, probablement un problème de configuration.

    EDIT :
    Elles sont en fait prises en compte mais étant donné le nombre de requêtes je ne le voyais pas. Après si j'ai bien compris il vaut mieux passer par l'annotation @group pour choisir ce que je charge en fonction du service appelé.

    Content d'avoir un début de piste en tous cas qui me semble encourageante.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Exemple Webservice REST en Delphi
    Par VLDG dans le forum REST
    Réponses: 1
    Dernier message: 29/05/2008, 00h18
  2. Exemple Webservice REST
    Par VLDG dans le forum Web & réseau
    Réponses: 1
    Dernier message: 29/05/2008, 00h18
  3. Approche Webservices RESTFul
    Par romainw dans le forum REST
    Réponses: 0
    Dernier message: 21/03/2008, 16h40
  4. Réponses: 4
    Dernier message: 07/02/2008, 12h34
  5. [SQL] y a-t-il trop de requêtes ?
    Par bisol dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 27/04/2007, 10h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo