Implémenter des limites de débit API dans votre application

Implémentation des limites de débit API dans votre application

Cet article accompagne une vidéo de la chaîne YouTube ShopifyDevs. Il est le troisième d'une série de quatre articles rédigés par Zameer Masjedee, ingénieur solutions pour Shopify Plus.

Dans la première partie de cette série, Introduction aux limites de débit, nous avons défini ce qu'est une limite de débit API et expliqué comment Shopify utilise l'algorithme du seau qui fuit, ou « leaky bucket ».

Dans le deuxième article, Limites de débit API et utilisation de GraphQL, nous avons abordé les nombreux avantages de GraphQL.

Dans ce troisième article, nous reprendrons tous les principes présentés dans les deux premières parties pour les appliquer concrètement dans une boutique de développement. Nous commencerons par les éléments dont vous avez besoin pour démarrer et nous verrons ensuite comment envoyer des requêtes en temps réel à l'API Shopify.

À la fin de cet article, vous serez capable d'envoyer des requêtes à l'API Shopify et vous saurez comment gérer de façon responsable votre limite de débit pour ne jamais la dépasser.

Pour commencer

Nous allons ici mettre en œuvre certaines des bonnes pratiques et idées que nous avons abordées précédemment, sans oublier notre logique métier de base. Nous travaillerons pour cela dans une application pour une boutique de développement. Nous utiliserons VS Code dans la démonstration, mais vous pouvez choisir votre IDE habituel.

Notre exemple de cas d'utilisation

Dans notre exemple de boutique, nous avons plusieurs produits, tous associés à une matière première précieuse. Il s'agit de bracelets en or, et comme nous le savons tous, le cours de l'or est très variable. Dans notre boutique de développement, nous créons les produits uniquement lorsque les commandes sont passées. Nous devons donc nous assurer que nous facturons un prix adapté pour chaque produit, en fonction des fluctuations du cours de l'or. Nous devons donc, à intervalles réguliers, mettre à jour les prix de l'ensemble du catalogue de produits selon les prix sur le marché.

Pour cela, nous devons suivre plusieurs étapes. Nous allons tout d'abord utiliser une application Node qui examinera les produits de notre boutique qui pourraient être concernés par les variations du prix de l'or. Ensuite, nous appliquerons certaines bonnes pratiques pour mettre à jour ces prix, tout en respectant la limite de débit API et en nous assurant que l'application ne soit pas bridée.

Si vous ne connaissez pas bien GraphQL, consultez avant de commencer la série de vidéos GraphQL proposée par Chuck Kosman, ingénieur lancement chez Shopify, sur la chaîne YouTube ShopifyDev. Il y présente tous les éléments essentiels de GraphQL dont nous parlerons dans cet article, notamment les alias et les variables. Regardez la première vidéo de cette série ci-dessous ou lisez le tutoriel correspondant.

Nous utilisons GraphQL pour contrôler nos variables et son package de requêtes pour pouvoir faire facilement des requêtes.

Dans ce tutoriel, nous n'allons pas créer une application Shopify officielle. Cela impliquerait d'utiliser l'outil Shopify App CLI pour la configurer. Nous souhaitons ici simplement tester le fonctionnement de notre application si elle incluait cette logique métier.

Comment récupérer les informations produits

Nous allons commencer par faire une requête. Examinons cette requête envoyée à Shopify :

La requête products(first: 200, query: “tag:gold”) permet de récupérer les 200 premiers produits qui ont la balise gold (or). Nous voulons aussi récupérer l'identifiant, id, de ces produits. Cela nous permet d'identifier facilement les produits concernés dans tout notre catalogue.

Nous devons modifier le prix de ces produits et nous savons que dans Shopify le prix est défini dans la variante. Nous devons donc examiner le paramètre variant associé à chaque produit. Enfin, nous intégrons dans notre requête les éléments id (identifiant) et weight (poids), car nous en aurons besoin pour calculer le nouveau prix que nous devrons appliquer.

Notez aussi que nous trichons un peu dans cet exemple en utilisant variants(first: 1). Nous savons que chacun de nos produits n'a qu'une seule variante, car c'est ainsi que nous avons configuré notre boutique. Vous devrez peut-être modifier ce chiffre pour voir si les produits ont plusieurs variantes. Shopify prend en charge jusqu'à 100 variantes. Si vous avez plusieurs variantes et utilisez donc une requête imbriquée, vos résultats seront paginés. Pour notre démonstration, variants(first: 1) est parfait.

Nous voyons ci-dessus que nous faisons une requête, graphQLClient.request, avec notre élément query. Nous allons capturer ces résultats et les afficher dans notre console console.log(JSON.stringify(queryData, undefined, 2)), en prenant soin de traiter toute erreur éventuelle avec (catch((error) => console.log(error)).

Voyons ce qui se passe lorsque nous exécutons cette requête :

 

La requête a renvoyé 200 produits différents. Si nous exécutons une autre requête, pour 10 produits simplement, elle renverra 10 produits. Il est important de comprendre que la réponse que nous obtenons commence par la clé products (produits) dans JSON, et que nous obtenons ensuite nos éléments edges (arêtes).

Chacune de ces arêtes représente l'objet ou le nœud qui nous intéresse, et qui est en fait un produit. Pour chacun de ces nœuds, nous récupérons l'identifiant et les variantes qui sont associés aux produits. Ce sont les informations dont nous avons besoin pour implémenter notre application.

Comment identifier la limite de débit API de votre application

Nous avons vu dans les précédents articles qu'un coût était associé à chaque requête ou mise à jour. Nous voulons savoir combien de requêtes ou de mises à jour nous pouvons encore faire sans dépasser notre limite de débit API. Shopify fournit cette information sous la forme d'une extension ajoutée à la réponse. Cependant, nous ne pourrons pas obtenir cette information avec la bibliothèque que nous avons utilisée ci-dessus en effectuant une requête standard, nous devrons utiliser une requête brute, rawRequest.

Utiliser rawRequest pour obtenir les métadonnées et la limite de débit disponible

Nous avons une autre version de notre requête sous la requête standard.

Elle utilise l'entrée rawRequest, qui exécute la même requête avec l'élément query, mais avec des informations supplémentaires. Nous ne récupérons pas simplement un ensemble de données, mais également les éléments extensions, headers (en-têtes), errors (erreurs) et status (statuts) qui font partie de cette requête.

Dans cet exemple, nous faisons exactement la même requête qu'au-dessus, mais nous capturons et affichons également la limite de débit restante après cette requête.

Exécutons cette requête :

En plus des données que nous capturons, nous voyons aussi qu'il nous reste 958 points disponibles dans notre limite de débit. Pour rappel, la limite maximale est de 1 000 points, il nous reste donc beaucoup de place dans notre « seau de requêtes ».

Mettre à jour chaque produit avec une mutation

Nous voulons ensuite mettre à jour ces produits. Nous devrons pour cela faire une mutation pour chaque produit individuellement.

Rappelez-vous qu'avec GraphQL, chaque propriété imbriquée ou champ de données capturé coûte un point, mais que chaque mutation vaut 10 points. Chacun de ces différents produits nous coûtera donc 10 points de notre limite de débit. Si nous exécutons plusieurs requêtes, nous allons rapidement épuiser nos 958 points.

Nous avons déjà récupéré nos données avec notre requête, nous devons donc maintenant les traiter. Nous voulons exécuter une mutation pour chacun des identifiants de produit renvoyés. Nous devons donc récupérer les identifiants de produit depuis la requête.

Comment allons-nous procéder ?

1ere étape : Indexer le tableau en définissant une nouvelle variable

Nous voyons que notre requête renvoie un tableau (array) de différents objets JSON, nous pouvons donc indexer ce tableau. Pour cela, nous allons définir une nouvelle variable.

Nous allons l'appeler const edges = data.products.edges. Nous pourrions même l'appeler const productedges = data.products.Edges. Elle envoie une requête qui examine toutes les données, en incluant les objets entiers, y compris les éléments product et edge.

2e étape : Construire une boucle for

Nous voulons construire une boucle pour chacun de ces éléments edge, afin de pouvoir accéder indépendamment à chaque produit. Nous allons pour cela écrire une boucle for.

for (let edge = 0; edge < productEdges.length; edge++)

Cette boucle for nous permet d'indexer chacun des tableaux que nous récupérons. Mais nous avons besoin d'informations spécifiques. Nous allons donc insérer le code suivant sous notre boucle for :

const productId = productEdges[edge].node.id

Il indique que nous voulons récupérer l'identifiant de produit productId qui est en fait égal (=) à nos productEdges. Nous devons ensuite indexer la clé node, puis la clé id.

Le prochain élément que nous demandons est l'identifiant de variante, variantId, à l'aide de ce code :

const variantId = productEdges[edge].node.variants.edges[0].node.id

Cela indique de la même façon que nous allons demander productEdges, imbriquer de nouveau l'élément node, mais cette fois aussi variants et edges. N'oubliez pas que les éléments edge sont des tableaux.

Idéalement, cette requête serait paginée sur différentes options, mais rappelons-nous que nous trichons un peu ici et que nous savons que nous avons une seule variante. Nous allons donc récupérer la première, [0]. Enfin, nous allons récupérer l'identifiant id dans l’élément node.

La requête pour les poids variantWeight est semblable à celle pour variantId :

const variantWeight = productEdges[edge].node.variants.edges[0].node.weight

Nous avons maintenant écrit toutes nos spécifications. Cela nous permet d'accéder à toutes les données dont nous aurons besoin pour implémenter la mutation. Nous allons maintenant voir comment mettre à jour le prix d'un produit.

Comment mettre à jour le prix des produits

Voyons ensemble les différentes étapes pour mettre à jour le prix des produits de façon responsable.

Tout d'abord, mettons à jour le prix du produit :

Ce code indique que le prix mis à jour (updatedPrice) est égal (=) au poids (variantWeight) du produit multiplié (*) par le prix au gramme de l'or (goldPricePerGram). Nous allons fixer ici un chiffre à deux décimales (toFixed(2)), qui représentent les centimes, car c'est ce que Shopify attend en termes de type de données dans l'entrée de la requête.

Lier la mutation à la boucle for

Nous allons ensuite extraire la mutation pour mettre à jour le prix d'un produit. Récupérons ici le texte que nous avons copié pour simplifier cette démonstration, et insérons-le dans notre fonction et notre boucle for.

Nous avons ainsi créé une variable appelée productUpdateMutation, et nous savons que dans Shopify, cette mutation est appelée productUpdate. Elle attend un champ d'entrée du type ProductInput. Elle renverra l'identifiant du produit qui a été mis à jour, car c'est ce que nous demandons.

Notre mutation est donc prête.

Créer l'objet productInput

L'étape suivante est de créer l'entrée. Consultons la documentation relative à l'objet productInput pour en savoir plus. Elle présente les différents champs d'entrée auxquels nous avons accès, dont l'identifiant id, les champs méta metafield ou les publications publication.

Dans notre exemple, ce sont les variantes qui nous intéressent, [ProductVariantIntput ! ], car c'est là que le prix est défini.

La documentation nous indique que nous devrons fournir un identifiant id, une clé variant et les propriétés associées à la variante du produit. Cela sera un autre identifiant, cette fois la clé price (prix). Voyons comment implémenter tout cela.

Écrire l'objet productInput

Nous créons une entrée, const productInput =. Nous insérons ensuite un identifiant, id: productID,, et des variantes, variants. L'élément variants est un tableau d’objets, puisqu’un produit peut avoir plusieurs variantes et chacune de ses variantes a un identifiant unique et un prix indépendant.

Indiquons donc id: variantId,, dans cet objet, ainsi que price: updatedPrice pour cette arrête ou produit spécifique, car nous allons tous les inclure dans une boucle, comme nous l'avons vu ci-dessus.

À chaque fois que nous calculons notre prix mis à jour updatedPrice, c'est pour un produit en particulier, et il est capturé dans notre objet productInput.

Nous avons donc maintenant défini tout ce dont nous avons besoin pour exécuter cette mutation, c'est parfait !

Dernière étape : appeler votre mutation

La dernière chose à faire est d'appeler cette mutation :

Nous allons donc écrire constant mutationData =, puis await graphQLClient.. pour attendre de façon synchrone la réponse du client GraphQL.

Nous allons ensuite faire une requête standard, request(productUpdateMutation, productInput)..

Nous voulons aussi repérer et enregistrer les éventuelles erreurs, avec catch((error)=> console.log(error)).

Avant d'exécuter cette requête, nous pouvons également demander à enregistrer une version convertie en chaîne de nos données de mutation, mutationData. Les paramètres supplémentaires permettront de formater les résultats en ajoutant des espaces autour des nouvelles lignes. Le code sera ainsi le suivant :

console.log(JSON.stringify(mutationData, undefined, 2))

Nous avons respecté le format défini dans la documentation pour l'objet productInput, mais nous devons l'imbriquer dans une objet, où nous spécifions bien qu'il s'agit d'une entrée input. Cela permet d'éviter toute confusion pour ce composant. C'est ce que nous faisons ici :

Nous pouvons maintenant enregistrer et exécuter notre requête. Notre boucle for devrait passer sur chacun des produits et mettre à jour leur prix. Voici l'affichage obtenu :

Ça marche ! Notre mutation passe sur chacun des produits, récupère les valeurs et fait la mise à jour. Il n'y a aucune erreur et nous récupérons bien l'identifiant du produit, c'est parfait.

Et ensuite ?

Que nous reste-t-il à faire ? Pour l'instant, nous ne connaissons pas la limite de débit encore disponible après avoir fait ces requêtes. Nous ne savons pas du tout si nous allons la dépasser bientôt. Nous aurons la réponse dans le prochain article de cette série, où nous apprendrons à capturer des informations, à optimiser notre travail et à utiliser la limite de débit de notre application de façon responsable.

Rejoignez le programme des partenaires de Shopify

Inscrivez-vous gratuitement au programme partenaire de Shopify. Accédez à des outils et ressources pour aider les marchands Shopify à développer leur activité et faites partie d’un écosystème riche en opportunités.

Devenir partenaire Shopify

Which method is right for you?Publié par Maud Leuenberger. Maud est la rédactrice en chef du blog français de Shopify.

Texte original par Zameer Masjedee. Traduction par Solenn Marchand.

Développez votre entreprise avec le programme Partenaires Shopify

En savoir plus