GraphQL - Partie 2

graphql-request /GitHub

Pour continuer ma compréhension du sujet, je reviens à une librairie “très” simple : graphql-request. Le but va être d’aller faire quelques requêtes sur l’API de GitHub.

C’est parti !

On commence simple :

  • npm init
  • npm install graphql-request

. Ensuite, il suffit de copier/adapter l’exemple fourni :

import { GraphQLClient } from 'graphql-request'

// La requête
const query = `{
    viewer {
        login
    }
    rateLimit {
        limit
        cost
        remaining
        resetAt
    }
}`;

// Création d'un client
const client = new GraphQLClient('https://api.github.com/graphql', {
    headers: {
      Authorization: 'Bearer [MACLE]',
    },
  })

client.request(query)
    .then(data => console.debug(JSON.stringify(data)) )
    .catch((error) => { console.error(JSON.stringify(error)); })

“et voilà” :

{
    "viewer": {
        "login": "devbieres"
    },
    "rateLimit": {
        "limit": 5000,
        "cost": 1,
        "remaining": 4997,
        "resetAt": "2018-02-23T09:22:34Z"
    }
}

.

Fini !

Bon, ben c’était rapide :)

Un élément intéressant

Même si c’était très rapide, il y a un point intéressant dans cette petite requête: la gestion du coût. En effet, en REST, une requête effectuée est par définition limité ou limitable. Il suffit de mettre en dure des limites et des protections. Par dans GraphQL : c’est pas trop le principe. De plus, dans une seule requête, il est possible de ramener la base de données :).

GitHub l’explique assez bien ici. En V3, c’était 5 000 requêtes par heure. En V4, c’est 5 000 unités de calcul par heure. Et la requête que j’effectue permet justement de savoir le crédit qu’il me reste. Sachant que pour savoir, cela me coûte :(.

Cette logique de passe au coût de calcul est finalement assez logique et de plus va dans le sens du “Pay-as-you-go” en vogue sur de nombreuses plateformes.

Un deuxième élément intéressant

La combinaison de requête: je récupère deux types d’informations en même temps. Ce qui vient renforcer le point précédent.

Une deuxième requête

Comment perdre du temps …

Dans la série “comment perdre du temps”, j’ai voulu récupérer les releases d’un projet. Le premier qui met venu : “angular”. Problème : pas moyen d’avoir les infos … je creuse, je change, rien … Par dépit, je tente un autre projet “material” et là, ça fonctionne. Je teste une dizaine d’autres et même résultat : cela fonctionne. Pourquoi cela ne fonctionne pas avec Angular … aucune idée.

La requête

const query = `query($owner: String!, $name: String!) {
    repository(owner:$owner, name:$name ) {
        releases(first:1, orderBy: { field: CREATED_AT, direction: DESC}) {
          edges {
            node {
              name
              tag {
                name
              }
            }
          }
        }
        tags:refs(refPrefix:"refs/tags/", first:1, orderBy:{ field: TAG_COMMIT_DATE, direction: DESC }) {
          edges {
            tag:node {
              name
            }
          }
        }
    }
    rateLimit {
           limit
           cost
           remaining
           resetAt
       }
}
`;

Pour rendre ma requête plus générique, je passe par des variables ce qui ne change pas grand chose dans l’absolu. Ensuite, le reste est assez explicite au niveau de la requête (avantage de GraphQL).

Résultats

Avec angular-cli :

{
  "data": {
    "repository": {
      "releases": {
        "edges": [
          {
            "node": {
              "name": "v6.0.0-beta.3",
              "tag": {
                "name": "v6.0.0-beta.3"
              }
            }
          }
        ]
      },
      "tags": {
        "edges": [
          {
            "tag": {
              "name": "v6.0.0-beta.3"
            }
          }
        ]
      }
    }
  }
}