Questions GraphQL et la RFC pour l'APi GVA

  • un schéma minimal

  • des schémas optionnel => diversité / innovation / hors du besoin de concertation a priori / potentiellement dédié à des outils spécifique / libre / évolutif …

1 Like

sinon le mode batch ça ressemble à ça

query testAll  {
  currency
  block(number:null){
    version
    number
    inner_hash
    medianTime
    unitbase
    powMin
    monetaryMass
    membersCount
    hash
    issuer 
    previousHash
    previousIssuer
    parameters 
    dividend
    issuersCount
    issuersFrame
    issuersFrameVar 
    certifications
    identities
    actives
    joiners
    leavers
    revoked 
    transactions{
      blockstamp
      blockstampTime
      thash 
      issuers
      inputs
      unlocks
      outputs
      locktime
      version 
      comment 
      signatures
    } 
    signature
    raw
  } 
  member(pubkey:"4weakHxDBMJG9NShULG1g786eeGh7wwntMeLZBDhJFni" ){
    pubkey
    uid
    signature
    createdOn {
      hash
      number
    }
  } 
  transactionsOfIssuer(issuer: "4weakHxDBMJG9NShULG1g786eeGh7wwntMeLZBDhJFni"){ 
    blockstamp
    blockstampTime
    locktime 
    issuers
    inputs
    unlocks
    outputs 
    comment
    signatures 
  } 
  transactionsOfReceiver(receiver: "4weakHxDBMJG9NShULG1g786eeGh7wwntMeLZBDhJFni"){
    blockstamp
    blockstampTime
    locktime 
    issuers
    inputs
    unlocks
    outputs 
    comment
    signatures
  } 
  sourcesOfPubkey(pub: "4weakHxDBMJG9NShULG1g786eeGh7wwntMeLZBDhJFni"){
    amount
    base
    conditions
    consumed
    identifier
    noffset
    type
  } 
  transactionByHash(hash: "8FDA19733F5FB458640E133419C17560647155A40B74425ECAC5E0933266049F"){
    block_number
    blockstamp 
    inputs
    outputs
    locktime
    comment
  } 
} 

dans une requête composé. au lieu de faire plusieurs requête on en fait une seule elle est décomposé coté serveur, exécute plusieurs fonctions, les agrège (toujours coté serveur et les renvois) .

donc en gros c’est assez pourris d’un point de vue client, ça veux dire que si une seule sous requête merde ou est lente, tu ralentit tout le chargement de la page ! c’est tout l’intêret des XHR, c’est plus dynamique, après c’est le client qui choisit comment il fait ça, et si un composant merde, probablement que tout le reste fonctionnera. par contre c’est chouette pour les test de non régression rapide :slight_smile:

Oui voila :slight_smile:
Dans un premier temps, concentrons nous sur l’objectif d’une 1ère version de GVA capable de remplacée BMA, ce sera déjà un bon objectif a atteindre :slight_smile:
Pour ce qui est de répondre a des besoins plus complexes ou/et plus exigeants en perf, ja préfère que ce ne soit pas commun a toutes les implémentations car :

  1. Chaque implémentation est dans un langage différent et une conception interne différente, donc certaines requêtes auront des perf variable selon l’implémentation. Bref, s’il y a des besoins de perf accrues pour certaines app clients il me semble indispensable de développer une API dédiée au besoin et pour une seule implémentation afin de tirer parti de façon dons c’est conçu derrière.
  2. On a tous des contraintes techniques différentes, on utilise des lib graphql différentes, donc plus on part sur un schéma complexe plus ça risque d’être en partie pas intégrable sur certaines implémentations.

Concernant les besoins spécifiques, on pourra en reparler en temps voulu, je peut dev une API spécifique coté Durs si le besoin est vraiment la, mais la priorité me semble etre de remplacer BMA qui est cencée etre obsolète :wink:


Les websocket sont une surcouche du protocole HTTP donc ça ne peut pas être plus rapide qu’HTTP. D’ailleurs ce n’est pas le protocole HTTP qui à des problèmes de perf, mais le coté synchrone des requêtes ainsi que la lourdeur de beaucoup de framework web.
M’enfin on est en 2019, on peut faire de l’asynchrone sur du HTTP, donc perso je vais partir sur du HTTP pour implémenter GVA dans Durs.

Le seul intérêt des websocket c’est la pas perf, c’est quand on a besoin de s’abonner a un flux distant pour recevoir de mises a jours en temps réel, dans graphql ça s’appelle les souscriptions ;).

1 Like

Les websockets auraient quand même l’avantage de réduire drastiquement l’overhead en gardant la même connexion ouverte pour toutes les requêtes de données.

oui mais c’est utile seulement pour les souscriptions ce que tu décrit. à priori c’est un peu l’option par défaut pour cela, donc le canal websocket GraphQL viendra, naturellement, avec les souscriptions, @Kimamila à du code qui tournes donc je vais pouvoir m’en inspirer.

Je ne sais pas, @vit laissait entendre qu’on pouvait utiliser les websockets aussi pour faire des requêtes GraphQL type query ?

oui si tu peux faire des subscriptions c’est très certainement possible… mais quel interet? la requête graphql fonctionne exactement comme un POST en REST, le websockets s’ouvrent via une requête http … oui tu peut mais c’est ce prendre la tete, ca met la pression coté serveur… car il ya une sesson à conserver… j’ai pas encore testé donc je veux pas trop m’avancer mais tfacon si tu peux faire un subscribe tu pourra faire une requête simple, donc ca viendra…

1 Like

GraphQL est “transport agnostic”, donc on peut utiliser TCP, HTTP, Websockets, mais aussi n’importe quel protocole de transport fait maison, binaire ou non.

It’s important to note that GraphQL is actually transport-layer agnostic . This means it can potentially be used with any available network protocol. So, it is potentially possible to implement a GraphQL server based on TCP, WebSockets, etc.

Voir https://www.howtographql.com/basics/3-big-picture/

Pour les souscriptions, il faut un transport qui puisse gérer des streams bi directionnel, mais là encore, GraphQL est agnostic, on utilise le protocole que l’on veut.

Delivery Agnostic

GraphQL subscriptions do not require any specific serialization format or transport mechanism. Subscriptions specifies algorithms for the creation of a stream, the content of each payload on that stream, and the closing of that stream. There are intentionally no specifications for message acknoledgement, buffering, resend requests, or any other quality of service (QoS) details. Message serialization, transport mechanisms, and quality of service details should be chosen by the implementing service.

Tiré de la dernière spec stable : https://facebook.github.io/graphql/June2018/#sec-Subscription

Si on regarde l’implémentation Apollo (javascript) on peut tout passer en websockets, pas seulement les souscriptions, ce qui simplifie la connexion :

You can then create WebSocket as full-transport, and pass all GraphQL operations over the WebSocket ( Query , Mutation and Subscription ), or use a hybrid network interface and execute Query and Mutation over HTTP, and only Subscription over the WebSocket.

https://www.apollographql.com/docs/react/advanced/network-layer.html

1 Like

@vit je sais bien tout ça mais de mon coté la seule librairie GraphQL mature que je puisse utilisée passe forcément par HTTP et ne supporte pas encore les souscriptions. Et je n’ai pas le temps de recoder moi même une implémentation de GraphQL en Rust, donc perso j’exposerai une api GVA via HTTP uniquement en sans websocket, je n’ai pas le choix :confused:

1 Like

On peut partir sur du http, mais c’est bon a savoir qu’à terme on pourrait changer la couche transport sans avoir a tout refaire dans les clients :slight_smile:

1 Like

Je comprends pas de soucis. :slightly_smiling_face: Je ne dis pas qu’il faut faire ceci ou cela, je dis juste que c’est possible en théorie, et je mets des liens pour références qui peuvent servir de documentation pour ceux qui feront des implémentations.

Les implémentations Rust, Python, Javascript vont évoluer et s’améliorer et comme dit Inso, si besoin un jour on pourra changer juste la couche transport !

1 Like

Hello !
La lib que tu utilises doit certainement te permettre de faire faire ton propre transport. C’est a dire manipuler les requêtes graphql, etc depuis ton code Rust.
Si par ailleurs tu sais faire des websockets (cf WS2P), alors le code a ajouter est vraiment minime. Je l’ai fait recemment pour Java, et je te mettrai le lien. Il n’y a que 2 cas a gérer : init de la connection, puis l’exécution d’une requête (query, mutation ou d’inscription).

Je trouve cela dommage de se priver des subscriptions, dans la mesure ou BMA proposait déjà un équivalent pour /ws/block et /ws/peer

Il fait au moins ces 2 d’inscriptions, non ?

1 Like

Après vérification c’est exact, mais c’est plus de boulot et plus de complexité pour celui qui s’en occupe donc il vas partir sur du HTTP. Si c’était moi qui le faisait je pourrait partir sur du websocket direct mais je doit laisser les contributeurs qui se sont proposer faire ce pour quoi ils se proposent sinon ils ne vont jamais apprendre et de toute façon je ne veut pas tout faire car je ne compte pas devenir un single point of failure.
Du coup Durs implémentera GVA en HTTP dans un 1er temps, on pourra toujours refactorer plus tard pour passer en websocket :slight_smile:
Il me semble préférable de commencer simple puis de complexifier par itérations progressives :wink:

@vit @kimamila @Inso ca y ai j’ai ajouté les documents réseaux au schéma de la RFC (heads et peers) : [feat] rfc gva: add network documents to schema (55682095) · Commits · nodes / common / doc · GitLab

1 Like

Merci @elois pour ces ajouts.
Après relecture rapide, voici mes remarques :

  • typo : “nodeID” au lieu de “nodeId”
  • renommer blockNumberAndHash en blockId ?
    Est-ce qu’on ne permettrait pas d’avoir le block directement la où il y a un blockNumberAndHash ?
    Ça évite de refaire une requête lorsqu’il y a besoin par exemple de la date du block.

Dans l’implémentation, ensuite, on peut détecter si le block est nécessaire, pour éviter de faire la requête inutilement.

1 Like

Merci c’est corrigé :slight_smile:

Non, le terme court d’origine était blockstamp car c’est le terme qu’on utilise coté serveur blockchain pour désigné le couple (blockNumber, blockHash). Si je l’ai modifié c’est uniquement pour que son titre soit explicite en vue d son contenu.
BlockId ce n’est pas explicite, c’est même très ambigu car selon le contexte le BlockId peut etre seulement le numéro du bloc ou le numéro + le hash.

Si c’est un besoin il vaut mieux faire un champ différent, car cela suit une logique différent :
→ le blockcstamp c’est dans le document ça fait parti de l’entité requetée.
→ le reste du block c’est une entité a part qu’il faut aller chercher.

Perso, je trouve blocknumberandhash très laid, et je préfère largement blockstamp, quitte à avoir un petit glossaire quelque part.

Blockstamp est explicite une fois que tu sais ce qu’il signifie. Mais en plus il est court et allégé à la lecture.

4 Likes

Tout a fait d’accord ! :slight_smile:

Oui, je le sais bien. Mais peu de clients ne voudront pas l’avoir, le bloc.
Par ailleurs, le “contexte” de la requête graphql permet de savoir si l’entité est demandée par le client, afin d’aller le bloc uniquement quand cela est necessaire.
C’est d’ailleurs ce qui fait la force du graphql, vis a vis des autres API d’accès aux données, a min avis.

Salut à tous,
je bosse ces jours-ci sur GVA, pour Cesium² avec « GVA inside » :).
Du coup, je voulais vous demander de rendre ce sujet public, si possible. les discussions sont techniques, et fortes utiles pour avancer sur GVA;

Mes travaux sur GVA

évolution de la RFC

Je vais commencé des commits dans la RFC. Il manque par exemple l’accès au pramètres de la BC (/bockchain/parameters dans BMA)

évolution de GVA-API (module Duniter)

Je vais faire des commits dans le module Duniter gva-api.

@cgeek, pourras tu regarder mes commit sur gva-api de temps en temps, histoire que je ne fasse pas trop de bétises ? :slight_smile:
Pour la pagination, peux tu m’aider un peu, par exemple avec un exemple d’implémentation (par exemple sur les transactions). Comme ca touche au code SQL, je ne suis pas sur de la porter de ces modifications. Faut il que je touche au code de Duniter ?

Socle technique de Cesium²

Une version minimaliste va bientot être publiée (code ici), avec juste l’accès à l’annuaire.

Je tente une double implémentation BMA/GVA (en fonction du nœud choisi dans les paramètres), afin de rester compatible avec les nœuds existant en BMA.

C’est une sorte de POC du socle technique.
Pour ceux qui veulent/peuvent regarder : c’est le bon moment pour donner votre avis, histoire d’avoir du code clair…

  • node 10 (pour la compilation)
  • Angular 7
  • Ionic 4
  • Lib GraphQL : Apollo

a++

5 Likes

Voici ma première merge request sur gva-api :slight_smile: Si @cgeek est ok, je ferai les suivantes directement sur le repo.

1 Like

Aussi d’accord pour publier cette discussion.

2 Likes