Quelle est la différence entre Falcor et GraphQL?


163

GraphQL se compose d'un système de type, d'un langage de requête et d'une sémantique d'exécution, d'une validation statique et d'une introspection de type, chacun décrit ci-dessous. Pour vous guider à travers chacun de ces composants, nous avons rédigé un exemple destiné à illustrer les différentes pièces de GraphQL.

- https://github.com/facebook/graphql

Falcor vous permet de représenter toutes vos sources de données distantes sous la forme d'un modèle de domaine unique via un graphique JSON virtuel. Vous codez de la même manière, quel que soit l'emplacement des données, que ce soit en mémoire sur le client ou sur le réseau sur le serveur.

- http://netflix.github.io/falcor/

Quelle est la différence entre Falcor et GraphQL (dans le contexte de Relay)?


5
consultez ce podcast où Jafar parle de la différence entre Relay / GraphQL et Falcor / JSON Graph youtu.be/WL54eYbTJUw?t=53m55s
gdi2290

Réponses:


131

J'ai regardé l' épisode 26 d'Angular Air: FalcorJS et Angular 2Jafar Husain explique comment GraphQL se compare à FalcorJS . Voici le résumé (paraphrasant):

  • FalcorJS et GraphQL s'attaquent au même problème (interrogation des données, gestion des données).
  • La distinction importante est que GraphQL est un langage de requête et FalcorJS ne l'est pas.
  • Lorsque vous demandez des ressources à FalcorJS, vous demandez très explicitement des séries finies de valeurs. FalcorJS prend en charge des choses comme les plages, par exemple genres[0..10]. Mais il ne prend pas en charge les requêtes ouvertes, par exemple genres[0..*].
  • GraphQL est basé sur un ensemble: donnez-moi tous les enregistrements où true, triez par ceci, etc. En ce sens, le langage de requête GraphQL est plus puissant que FalcorJS.
  • Avec GraphQL, vous disposez d'un langage de requête puissant, mais vous devez interpréter ce langage de requête sur le serveur.

Jafar soutient que dans la plupart des applications, les types de requêtes qui vont du client au serveur partagent la même forme. Par conséquent, le fait d'avoir des opérations spécifiques et prévisibles comme obtenir et définir expose plus d'opportunités pour tirer parti du cache. De plus, de nombreux développeurs sont familiarisés avec le mappage des requêtes à l'aide d'un simple routeur en architecture REST.

La discussion de fin porte sur la question de savoir si la puissance fournie avec GraphQL l'emporte sur la complexité.


82

J'ai maintenant écrit des applications avec les deux bibliothèques et je peux être d'accord avec tout dans l'article de Gajus, mais j'ai trouvé des choses différentes les plus importantes dans ma propre utilisation des frameworks.

  • La plus grande différence pratique est probablement que la plupart des exemples et probablement le travail effectué jusqu'à présent sur GraphQL ont été concentrés sur l'intégration de GraphQL avec Relay - le système de Facebook pour intégrer les widgets ReactJS avec leurs besoins en données. FalcorJS, d'autre part, a tendance à agir séparément du système de widgets, ce qui signifie à la fois qu'il peut être plus facile de s'intégrer dans un client non-React / Relay et qu'il en fera moins pour vous automatiquement en termes de correspondance des dépendances de données de widget avec des widgets.
  • Le revers de la médaille de FalcorJS étant flexible dans les intégrations côté client, c'est qu'il peut être très avisé sur la façon dont le serveur doit agir. FalcorJS a en fait une capacité directe "Appeler cette requête via HTTP" - bien que Jafar Husain ne semble pas en parler beaucoup - et une fois que vous les incluez, la façon dont les bibliothèques clientes réagissent aux informations du serveur est assez similaire sauf que GraphQL / Relay ajoute une couche de configuration. Dans FalcorJS, si vous renvoyez une valeur pour movie, votre valeur de retour est préférable de dire «movie», alors que dans GraphQL, vous pouvez décrire que même si la requête renvoie «film», vous devez la placer dans le magasin de données côté client sous le nom «movie ». - cela fait partie du compromis puissance / complexité mentionné par Gajus.
  • Sur une base pratique, GraphQL et Relay semblent être plus développés. Jafar Husain a mentionné que la prochaine version de l'interface Netflix fonctionnera au moins en partie sur FalcorJS alors que l'équipe Facebook a mentionné qu'elle utilisait une version de la pile GraphQL / Relay en production depuis plus de 3 ans.
  • La communauté de développeurs open source autour de GraphQL et Relay semble prospérer. Il existe un grand nombre de projets de support bien suivis autour de GraphQL et Relay alors que j'en ai personnellement trouvé très peu autour de FalcorJS. De plus, le référentiel github de base pour Relay ( https://github.com/facebook/relay/pulse ) est nettement plus actif que le référentiel github pour FalcorJS ( https://github.com/netflix/falcor/pulse ). Lorsque j'ai retiré le repo Facebook pour la première fois, les exemples étaient cassés. J'ai ouvert un problème github et il a été résolu en quelques heures. D'un autre côté, le problème github que j'ai ouvert sur FalcorJS n'a reçu aucune réponse officielle depuis deux semaines.

1
GraphQL (2012) existe bien avant React et Relay, donc votre premier point n'est peut-être pas tout à fait exact.
Burgi

Vous pouvez avoir raison. Je ne suis pas un facebook, donc je ne peux pas vraiment parler de l'histoire. Mon commentaire vient davantage de l'état actuel de la documentation et des discussions de Facebook. Ils ont été présentés au monde en tant que compagnons ( facebook.github.io/react/blog/2015/02/20/… ) et les deux remontent à pas mal de chemin. J'ai vu des commentaires vagues sur Relay remontant à 3 ans dans des commentaires datés du début de 2015, il est donc possible que les deux aient été développés en interne pendant plusieurs années avant d'être présentés au monde extérieur. Mais je n'ai certainement aucune connaissance particulière.
OverclockedTim

25

Lee Byron l' un des ingénieurs derrière GraphQL a fait une AMA sur hashnode , voici sa réponse à cette question:

  • Falcor renvoie Observables, GraphQL juste des valeurs. Pour la façon dont Netflix voulait utiliser Falcor, cela a beaucoup de sens pour eux. Ils font plusieurs demandes et présentent les données au fur et à mesure qu'elles sont prêtes, mais cela signifie également que le développeur client doit travailler directement avec les Observables. GraphQL est un modèle de requête / réponse, et renvoie JSON, qui est alors trivialement facile à utiliser. Relay ajoute une partie du dynamisme que Falcor présente tout en ne conservant que des valeurs simples.
  • Système de type. GraphQL est défini en termes de système de types, et cela nous a permis de construire de nombreux outils intéressants comme GraphiQL, des générateurs de code, la détection d'erreurs, etc. Falcor est beaucoup plus dynamique, ce qui est précieux en soi mais limite la capacité de faire ce genre de chose.
  • Utilisation du réseau. GraphQL a été conçu à l'origine pour exploiter le fil d'actualités de Facebook sur des appareils bas de gamme sur des réseaux encore plus bas de gamme.Il se donne donc beaucoup de mal pour vous permettre de déclarer tout ce dont vous avez besoin dans une seule demande réseau afin de minimiser la latence. Falcor, en revanche, effectue souvent plusieurs allers-retours pour collecter des données supplémentaires. C'est vraiment juste un compromis entre la simplicité du système et le contrôle du réseau. Pour Netflix, ils traitent également des appareils très bas de gamme (par exemple, une clé Roku), mais l'hypothèse est que le réseau sera suffisamment bon pour diffuser de la vidéo.

Edit: Falcor peut en effet traiter des requêtes par lots , rendant le commentaire sur l'utilisation du réseau inexact. Merci à @PrzeoR


4
PAS VRAI -> "" "Falcor, par contre, effectue souvent plusieurs allers-retours pour collecter des données supplémentaires. Il ne s'agit en réalité que d'un compromis entre la simplicité du système et le contrôle du réseau." "". Vérifiez simplement la fonctionnalité Falcor Batch et c'est la même chose ou même mieux que dans Relay.
PrzeoR

1
@PrzeoR Merci pour la correction! J'ai édité le post!
YasserKaddour

vous êtes les bienvenus :-) liés à FalcorJS vérifiez pour plus de détails ici: reactjs.co/2016/02/03
...

Excellent article en effet Falcor est génial, malheureusement je suis un développeur Scala et il n'y a pas d'implémentation Falcor dans Scala et dans aucun autre langage d'ailleurs, cependant il y a Sangria une excellente implémentation GraphQL dans Scala
YasserKaddour

Et il existe une autre alternative au relais qui utilise redux comme apollo-client et cashay
YasserKaddour

21

MISE À JOUR: J'ai trouvé le commentaire très utile sous mon article que je souhaite partager avec vous en complément du contenu principal: entrez la description de l'image ici

En ce qui concerne le manque d'exemples, vous pouvez trouver le repo awesome-falcorjs utilisateur, il existe différents exemples d'utilisation du CRUD d'un Falcor: https://github.com/przeor/awesome-falcorjs ... Deuxième chose, il y a un livre appelé " Maîtriser le développement Full Stack React "qui inclut également Falcor (bon moyen d'apprendre à l'utiliser):

entrez la description de l'image ici

POSTE ORGINAL CI-DESSOUS:

FalcorJS ( https://www.facebook.com/groups/falcorjs/ ) est beaucoup plus simple pour être efficace par rapport à Relay / GraphQL.

La courbe d'apprentissage pour GraphQL + Relay est ÉNORME: entrez la description de l'image ici

Dans mon bref résumé: Optez pour Falcor. Utilisez Falcor dans votre prochain projet jusqu'à ce que VOUS ayez un gros budget et beaucoup de temps d'apprentissage pour votre équipe, puis utilisez RELAY + GRAPHQL.

GraphQL + Relay a une API énorme dans laquelle vous devez être efficace. Falcor a une petite API et est très facile à comprendre pour tout développeur front-end familiarisé avec JSON.

Si vous avez un projet AGILE avec des ressources limitées -> alors optez pour FalcorJS!

MON avis SUBJECTIF: FalcorJS est 500% plus facile à être efficace en javascript full-stack.

J'ai également publié des kits de démarrage FalcorJS sur mon projet (+ d'autres exemples de projets falcor full-stack): https://www.github.com/przeor

Pour être plus dans les détails techniques:

1) Lorsque vous utilisez Falcor, vous pouvez utiliser à la fois sur le front-end et le backend:

importer du falcor de «falcor»;

puis construisez votre modèle basé sur.

... vous avez également besoin de deux bibliothèques simples à utiliser sur le backend: a) falcor-express - vous l'utilisez une fois (ex. app.use ('/ model.json', FalcorServer.dataSourceRoute (() => new NamesRouter ())) ). Source: https://github.com/przeor/falcor-netflix-shopping-cart-example/blob/master/server/index.js

b) falcor-router - vous y définissez des routes SIMPLES (ex. route: '_view.length' ). Source: https://github.com/przeor/falcor-netflix-shopping-cart-example/blob/master/server/router.js

Falcor est un jeu d'enfant en termes de courbe d'apprentissage.

Vous pouvez également consulter la documentation qui est beaucoup plus simple que la bibliothèque de FB et consulter également l'article " pourquoi vous devriez vous soucier de falcorjs (netflix falcor) ".

2) Relay / GraphQL ressemble plus à un énorme outil d'entreprise.

Par exemple, vous avez deux documentations différentes qui parlent séparément:

a) Relay: https://facebook.github.io/relay/docs/tutorial.html - Conteneurs - Routes - Root Container - Ready State - Mutations - Network Layer - Babel Relay Plugin - GRAPHQL

  • Spécification du relais GraphQL
  • Identification d'objets
  • Lien
  • Les mutations
  • Lectures complémentaires
  • RÉFÉRENCE API

  • Relais

  • RelayContainer
  • Relais.Route
  • Relay.RootContainer
  • Relay.QL
  • Relais.Mutation
  • Relay.PropTypes
  • Relay.Store
  • INTERFACES

  • RelayNetworkLayer

  • RelayMutationRequest
  • RelayQueryRequest

b) GrapQL: https://facebook.github.io/graphql/

  • 2Langue
  • 2.1 Texte source
  • 2.1.1 Unicode
  • 2.1.2 Espace blanc
  • 2.1.3 Terminateurs de ligne
  • 2.1.4 Commentaires
  • 2.1.5 Virgules insignifiantes
  • 2.1.6 Jetons exotiques
  • 2.1.7 Jetons ignorés
  • 2.1.8Ponctuateurs
  • 2.1.9 Noms
  • 2.2 Document de requête
  • 2.2.1Opérations
  • 2.2.2 Ensembles de sélection
  • 2.2.3 Champs
  • 2.2.4Arguments
  • 2.2.5 Alias ​​de champ
  • 2.2.6 Fragments
  • 2.2.6.1 Conditions de type
  • 2.2.6.2 Fragments en ligne
  • 2.2.7 Valeurs d'entrée
  • 2.2.7.1 Valeur Int
  • 2.2.7.2 Valeur flottante
  • 2.2.7.3 Valeur booléenne
  • 2.2.7.4 Valeur de chaîne
  • 2.2.7.5 Valeur enum
  • 2.2.7.6 Valeur de liste
  • 2.2.7.7 Valeurs des objets d'entrée
  • 2.2.8Variables
  • 2.2.8.1Utilisation variable dans les fragments
  • 2.2.9 Types d'entrée
  • 2.2.10Directives
  • 2.2.10.1 Directives sur les fragments
  • Système 3Type
  • 3.1Types
  • 3.1.1Scalaires
  • 3.1.1.1 Scalaires intégrés
  • 3.1.1.1.1Int
  • 3.1.1.1.2 Flottant
  • 3.1.1.1.3 Chaîne
  • 3.1.1.1.4Booléen
  • 3.1.1.1.5ID
  • 3.1.2Objets
  • 3.1.2.1 Arguments du champ objet
  • 3.1.2.2 Désapprobation du champ objet
  • 3.1.2.3 Validation du type d'objet
  • 3.1.3 Interfaces
  • 3.1.3.1 Validation du type d'interface
  • 3.1.4Unions
  • 3.1.4.1 Validation du type d'union
  • 3.1.5 Enums
  • 3.1.6 Objets d'entrée
  • 3.1.7 Listes
  • 3.1.8Non-Null
  • 3.2Directives
  • 3.2.1@skip
  • 3.2.2@inclure
  • 3.3 Types de démarrage
  • 4Introspection
  • 4.1 Principes généraux
  • 4.1.1 Conventions de nom
  • 4.1.2 Documentation
  • 4.1.3Déprécation
  • 4.1.4 Introspection de nom de type
  • 4.2 Introspection du schéma
  • 4.2.1Le type "__Type"
  • 4.2.2 Types de types
  • 4.2.2.1Scalaire
  • 4.2.2.2Objet
  • 4.2.2.3 Union
  • 4.2.2.4Interface
  • 4.2.2.5 Énum
  • 4.2.2.6 Objet d'entrée
  • 4.2.2.7 Liste
  • 4.2.2.8Non nul
  • 4.2.2.9 Liste de combinaison et non-nul
  • 4.2.3Le type __Field
  • 4.2.4 Le type __InputValue
  • 5Validation
  • 5.1Opérations
  • 5.1.1 Définitions des opérations nommées
  • 5.1.1.1 Unicité du nom de l'opération
  • 5.1.2 Définitions des opérations anonymes
  • 5.1.2.1 Opération anonyme seule
  • 5.2 Champs
  • 5.2.1 Sélections de champ sur les types d'objets, d'interfaces et d'unions
  • 5.2.2 Fusion de sélection de champ
  • 5.2.3 Sélections des champs de feuilles
  • 5.3Arguments
  • 5.3.1 Noms des arguments
  • 5.3.2 Unicité de l'argument
  • 5.3.3 Exactitude du type des valeurs d'argument
  • 5.3.3.1 Valeurs compatibles
  • 5.3.3.2 Arguments requis
  • 5.4 Fragments
  • 5.4.1 Déclarations de fragmentation
  • 5.4.1.1 Unicité du nom du fragment
  • 5.4.1.2 Existence du type de propagation de fragmentation
  • 5.4.1.3 Fragments sur les types composites
  • 5.4.1.4 Les fragments doivent être utilisés
  • 5.4.2 Tartinades de fragmentation
  • 5.4.2.1 Définition de la cible d'épandage de fragmentation
  • 5.4.2.2 Les pâtes à tartiner ne doivent pas former de cycles
  • 5.4.2.3 La propagation des fragments est possible
  • 5.4.2.3.1Object Spreads In Object Scope
  • 5.4.2.3.2 Spreads abstraits dans la portée de l'objet
  • 5.4.2.3.3 Spreads d'objets dans une portée abstraite
  • 5.4.2.3.4 Spreads abstraites dans une portée abstraite
  • 5.5Valeurs
  • 5.5.1 Unicité du champ d'objet d'entrée
  • 5.6Directives
  • 5.6.1 Les directives sont définies
  • 5.7Variables
  • 5.7.1 Unicité variable
  • 5.7.2 Les valeurs par défaut des variables sont correctement saisies
  • 5.7.3 Les variables sont des types d'entrée
  • 5.7.4 Toutes les utilisations de variables définies
  • 5.7.5 Toutes les variables utilisées
  • 5.7.6 Toutes les utilisations variables sont autorisées
  • 6Exécution
  • 6.1 Évaluation des demandes
  • 6.2 Variables coercitives
  • 6.3 Évaluation des opérations
  • 6.4 Évaluation des ensembles de sélection
  • 6.5Évaluation d'un ensemble de champs groupés
  • 6.5.1 Entrées de champ
  • 6.5.2 Évaluation normale
  • 6.5.3 Exécution en série
  • 6.5.4 Gestion des erreurs
  • 6.5.5 Annulation
  • 7Réponse
  • 7.1 Format de sérialisation
  • 7.1.1 Sérialisation JSON
  • 7.2 Format de réponse
  • 7.2.1 Données
  • 7.2.2Erreurs
  • AAppendice: Conventions de notation
  • A.1 Grammaire sans contexte
  • A.2 Grammaire lexicale et syntaxique
  • A.3 Notation de la grammaire
  • A.4 Sémantique de la grammaire
  • A.5Algorithmes
  • Annexe: Résumé de la grammaire
  • B.1 Jetons ignorés
  • B.2 Jetons exotiques
  • B.3 Document de requête

C'est ton choix:

Falcor JS VERSUS, simple et court documenté, outil de qualité professionnelle avec une documentation longue et avancée comme GraphQL & Relay

Comme je l'ai déjà dit, si vous êtes un développeur frontal qui comprend l'idée d'utiliser JSON, alors l'implémentation de graphes JSON de l'équipe Falcor est le meilleur moyen de réaliser votre projet de développement full-stack.


13
Réponse subjective. N'inclut pas la comparaison technique. Plus approprié comme commentaire.
Gajus

2
@GajusKuizinas réponse subjective? Vérifiez la documentation des deux ;-) Je dis simplement que Falcor est plus rapide et plus rapide à apprendre - et c'est un fait ;-) aussi j'ai travaillé avec les deux - la simplicité l'emportera sur le long terme même si FB fait un excellent travail avec hype ;-)
PrzeoR

2
Ce n'est qu'une opinion et cela ne répond pas du tout à la question.
Michał Miszczyszyn

14
Je pense que c'est une excellente réponse, au fait, la courbe d'apprentissage d'une technologie n'est pas nécessairement subjective et peut être facilement mesurée, les faits sont présentés ici afin que des conclusions claires puissent être extraites. Dans le monde réel, des professionnels sérieux prennent ces faits en considération. C'est après tout une question ouverte, qui bénéficie clairement de réponses comme celle-ci.
bmaggi

2
Je suis d'accord avec @MorgenCheng, voté à la hausse! J'ai fait le tour ces dernières semaines en évaluant GraphQL / Relay, Cashay, Redux et maintenant Falcor, et je suis à 100% d'accord avec PrzeoR. Relay et GraphQL sont des technologies géniales, mais elles nécessitent beaucoup plus de cerveau et sont plus difficiles à faire pour les débutants. Il y a beaucoup d'apprentissage impliqué. L'inconvénient de Falcor, c'est le manque d'exemples pour une application complète basée sur CRUD. Et j'adorerais voir les projets PostgreSQL et RethinkDB cracher JsonGraph.
Dom

5

En bref, Falcor ou GraphQL ou Restful résolvent le même problème - fournissent un outil pour interroger / manipuler efficacement les données.

Leur différence réside dans la manière dont ils présentent leurs données:

  • Falcor veut que vous pensiez leurs données comme une très grande arborescence JSON virtuelle, et utilise get , set et call pour lire et écrire des données.
  • GraphQL veut que vous pensiez leurs données comme un groupe d'objets typés prédéfinis, et utilise des requêtes et des mutations pour lire, écrire des données.
  • Restful veut que vous pensiez leurs données comme un groupe de ressources et utilise des verbes HTTP pour lire et écrire des données.

Chaque fois que nous avons besoin de fournir des données pour l'utilisateur, nous nous retrouvons avec quelque chose d'aimé: client -> requête -> {une couche de traduction de la requête en opérations de données} -> données.

Après avoir lutté avec GraphQL, Falcor et JSON API (et même ODdata), j'ai écrit ma propre couche de requête de données . C'est plus simple, plus facile à apprendre et plus équivalent avec GraphQL.

Découvrez-le sur:
https://github.com/giapnguyen74/nextql

Il s'intègre également à featherjs pour des requêtes / mutations en temps réel. https://github.com/giapnguyen74/nextql-feathers


2

OK, partez d' une différence simple mais importante, GraphQL est une requête basée sur Falcor, mais pas!

Mais comment ils vous aident?

Fondamentalement, ils nous aident tous les deux à gérer et à interroger les données, mais GraphQL a un modèle req / res et renvoie les données au format JSON , essentiellement l'idée dans GraphQL est d'avoir une seule demande pour obtenir toutes vos données dans un seul objectif ... Aussi, avoir une réponse exacte en ayant une demande exacte, donc quelque chose à exécuter sur Internet bas débit et des appareils mobiles, comme les réseaux 3G ... Donc, si vous avez beaucoup d'utilisateurs mobiles ou pour certaines raisons, vous aimeriez avoir moins de demandes et une réponse plus rapide , utilisez GraphQL ... Bien que Faclor n'en soit pas trop loin, alors lisez la suite ...

D'autre part, Falcor by Netflix, a généralement une demande supplémentaire (généralement plus d'une fois) pour récupérer toutes vos données, même s'ils essaient de les améliorer en une seule demande ... Falcor est plus limité pour les requêtes et n'a pas de pré -des aides de requêtes définies comme range et etc ...

Mais pour plus de précisions, voyons comment chacun d'eux se présente:

GraphQL, un langage de requête pour votre API

GraphQL est un langage de requête pour les API et un moteur d'exécution pour répondre à ces requêtes avec vos données existantes. GraphQL fournit une description complète et compréhensible des données de votre API, donne aux clients le pouvoir de demander exactement ce dont ils ont besoin et rien de plus, facilite l'évolution des API au fil du temps et permet des outils de développement puissants.

Envoyez une requête GraphQL à votre API et obtenez exactement ce dont vous avez besoin, ni plus ni moins. Les requêtes GraphQL renvoient toujours des résultats prévisibles. Les applications utilisant GraphQL sont rapides et stables car elles contrôlent les données qu'elles obtiennent, pas le serveur.

Les requêtes GraphQL accèdent non seulement aux propriétés d'une ressource, mais suivent également en douceur les références entre elles. Alors que les API REST typiques nécessitent un chargement à partir de plusieurs URL, les API GraphQL obtiennent toutes les données dont votre application a besoin en une seule demande. Les applications utilisant GraphQL peuvent être rapides même sur des connexions de réseau mobile lentes.

Les API GraphQL sont organisées en termes de types et de champs, et non de points de terminaison. Accédez à toutes les capacités de vos données à partir d'un seul point de terminaison. GraphQL utilise des types pour garantir que les applications ne demandent que ce qui est possible et fournissent des erreurs claires et utiles. Les applications peuvent utiliser des types pour éviter d'écrire du code d'analyse manuelle.


Falcor, une bibliothèque JavaScript pour une récupération efficace des données

Falcor vous permet de représenter toutes vos sources de données distantes sous la forme d'un modèle de domaine unique via un graphique JSON virtuel. Vous codez de la même manière, peu importe où se trouvent les données, que ce soit en mémoire sur le client ou sur le réseau sur le serveur.

Une syntaxe de chemin de type JavaScript facilite l'accès à autant ou aussi peu de données que vous le souhaitez, quand vous le souhaitez. Vous récupérez vos données à l'aide d'opérations JavaScript familières telles que get, set et call. Si vous connaissez vos données, vous connaissez votre API.

Falcor parcourt automatiquement les références dans votre graphique et fait des requêtes si nécessaire. Falcor gère de manière transparente toutes les communications réseau, en groupant et en déduquant de manière opportuniste les demandes.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.