Construire une API avec des fonctions Gatsby

Publié: 2022-03-10
Résumé rapide ↬ Dans ce didacticiel, Paul Scanlon explique comment créer une API à l'aide des fonctions Gatsby et ce que vous devez garder à l'esprit lors du déploiement sur Gatsby Cloud.

Vous avez probablement entendu parler des fonctions sans serveur, mais si ce n'est pas le cas, les fonctions sans serveur fournissent des fonctionnalités généralement associées aux technologies côté serveur qui peuvent être implémentées avec le code frontal sans être pris dans les infrastructures côté serveur.

Avec le code côté serveur et côté client coexistant dans la même base de code, les développeurs frontaux comme moi peuvent étendre la portée de ce qui est possible en utilisant les outils qu'ils connaissent et aiment déjà.

Limites

La coexistence est excellente, mais il y a au moins deux scénarios que j'ai rencontrés dans lesquels l'utilisation de fonctions sans serveur de cette manière n'était pas tout à fait adaptée à la tâche à accomplir. Ils sont les suivants :

  1. Le frontal ne pouvait pas prendre en charge les fonctions sans serveur.
  2. La même fonctionnalité était requise par plus d'un frontal.

Pour aider à fournir un contexte, voici un exemple des points 1 et 2 nommés ci-dessus. Je maintiens un projet Open-source appelé MDX Embed, vous verrez sur le site de documentation que ce n'est pas un site Web Gatsby. Il a été construit à l'aide de Storybook et Storybook seul ne fournit aucune capacité de fonction sans serveur. Je voulais mettre en place des contributions "Pay what you want" pour aider à financer ce projet et je voulais utiliser Stripe pour permettre des paiements sécurisés mais sans un "backend" sécurisé Cela n'aurait pas été possible.

En extrayant cette fonctionnalité dans une API construite avec les fonctions Gatsby, j'ai pu obtenir ce que je voulais avec MDX Embed et également réutiliser la même fonctionnalité et activer la fonctionnalité « Payez ce que vous voulez » pour mon blog.

Vous pouvez en savoir plus sur la façon dont j'ai fait cela ici : Monétiser un logiciel open-source avec les fonctions Gatsby et Stripe.

C'est à ce stade que l'utilisation des fonctions Gatsby peut agir comme une sorte de back-end pour le front-end ou BFF et le développement de cette manière s'apparente davantage au développement d'une API ( Application Programming Interface ).

Les API sont utilisées par le code frontal pour gérer des éléments tels que les connexions, la récupération de données en temps réel ou les tâches sécurisées qui ne sont pas correctement gérées par le navigateur seul. Dans ce didacticiel, j'expliquerai comment créer une API à l'aide de Gatsby Functions et la déployer sur Gatsby Cloud.

Plus après saut! Continuez à lire ci-dessous ↓

Vérifications avant le vol

Les fonctions Gatsby fonctionnent lorsqu'elles sont déployées sur Gatsby Cloud ou Netlify, et dans ce didacticiel, j'expliquerai comment déployer sur Gatsby Cloud, vous devrez donc d'abord vous inscrire et créer un compte gratuit.

Vous aurez également besoin d'un compte GitHub, GitLab ou BitBucket, c'est ainsi que Gatsby Cloud lit votre code puis construit votre « site », ou dans ce cas, l'API.

Pour les besoins de ce tutoriel, j'utiliserai GitHub. Si vous préférez aller de l'avant, le code de l'API de démonstration terminé peut être trouvé sur mon GitHub.

Commencer

Créez un nouveau répertoire quelque part sur votre lecteur local et exécutez ce qui suit dans votre terminal. Cela mettra en place un package.json par défaut.

 npm init -y

Dépendances

Tapez ce qui suit dans votre terminal pour installer les dépendances requises.

 npm install gatsby react react-dom

pages

Il est probable que votre API n'aura pas de "pages", mais pour éviter de voir l' avertissement de page manquante par défaut de Gatsby lorsque vous visitez l'URL racine dans le navigateur, ajoutez ce qui suit à la fois à src/pages/index.js et src/pages/404.js .

 //src/pages/index.js & src/pages/404.js export default () => null;

API

Ajoutez ce qui suit à src/api/my-first-function.js .

J'expliquerai un peu plus tard ce que signifie 'Access-Control-Allow-Origin', '*' , mais en bref, cela garantit que vos API d'autres origines ne sont pas bloquées par CORS.

 //src/api/my-first-function.js export default function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); res.status(200).json({ message: 'A ok!' }); }

Scénarios

Ajoutez ce qui suit à package.json .

 //package.json ... "scripts": { "develop": "gatsby develop", "build": "gatsby build" }, ...

Démarrer le serveur de développement Gatsby

Pour faire tourner le serveur de développement Gatsby, exécutez ce qui suit dans votre terminal.

 npm run develop

Faire une demande depuis le navigateur

Avec le serveur de développement de Gatsby en cours d'exécution, vous pouvez visiter http://localhost:8000/api/my-first-function, et puisqu'il s'agit d'une simple requête GET , vous devriez voir ce qui suit dans votre navigateur.

 { "message": "A ok!" }

Toutes nos félicitations

Vous venez de développer une API à l'aide des fonctions Gatsby.

Déployer

Si vous voyez la réponse ci-dessus dans votre navigateur, il est sûr de supposer que votre fonction fonctionne correctement localement, dans les étapes suivantes, j'expliquerai comment déployer votre API sur Gatsby Cloud et y accéder à l'aide d'une requête HTTP de CodeSandbox.

Pousser le code vers Git

Avant de tenter de déployer sur Gatsby Cloud, vous devez avoir envoyé votre code au fournisseur Git de votre choix.

Nuage de Gatsby

Connectez-vous à votre compte Gatsby Cloud et recherchez le gros bouton violet indiquant « Ajouter un site + ».

Capture d'écran du site d'ajout de Gatsby Cloud
Ajouter un site à Gatsby Cloud. ( Grand aperçu )

À l'étape suivante, il vous sera demandé soit d'importer à partir d'un référentiel Git, soit de démarrer à partir d'un modèle, de sélectionner Import from Git Repository et de cliquer sur next .

Capture d'écran sélectionnez l'importation à partir d'un référentiel Git
Sélectionnez importer depuis un référentiel Git. ( Grand aperçu )

Comme mentionné ci-dessus, Gatsby Cloud peut se connecter à GitHub, GitLab ou Bitbucket. Sélectionnez votre fournisseur Git préféré et cliquez sur next .

Capture d'écran de la sélection du fournisseur Gatsby Cloud Git
Choisissez parmi votre fournisseur Git préféré. ( Grand aperçu )

Avec votre fournisseur Git connecté, vous pouvez rechercher votre référentiel et donner un nom à votre site.

Capture d'écran de la recherche Gatsby Cloud du site du fournisseur Git
Recherchez votre site auprès de votre fournisseur Git. ( Grand aperçu )

Une fois que vous avez sélectionné votre référentiel et nommé votre site, cliquez sur next .

Vous pouvez ignorer les "Intégrations" et "Configuration" car nous n'en aurons pas besoin.

Si tout s'est déroulé comme prévu, vous devriez voir quelque chose de similaire à la capture d'écran ci-dessous.

Capture d'écran du site déployé avec succès
'site' construit et déployé avec succès sur Gatsby Cloud. ( Grand aperçu )

Vous verrez près du haut sur le côté gauche de l'écran une URL qui se termine par gatsbyjs.io , ce sera l'URL de votre API et toutes les fonctions que vous créez sont accessibles en ajoutant /api/name-of-function à la fin de cette URL.

Par exemple, la version déployée complète de my-first-function.js pour mon API de démonstration est la suivante :

API de démonstration : Ma première fonction .

Tester votre API

Visiter l'URL de votre API est une chose, mais ce n'est pas vraiment la façon dont les API sont généralement utilisées. Idéalement, pour tester votre API, vous devez faire une demande à la fonction à partir d'une origine totalement indépendante.

C'est ici que res.setHeader('Access-Control-Allow-Origin', '*'); vient à la rescousse. Bien qu'il ne soit pas toujours souhaitable d'autoriser n'importe quel domaine (site Web) à accéder à vos fonctions, pour la plupart, les fonctions publiques ne sont que cela, publiques. Définir l'en-tête Access Control sur une valeur de * signifie que n'importe quel domaine peut accéder à votre fonction, sans cela, tout domaine autre que le domaine sur lequel l'API est hébergée sera bloqué par CORS.

Voici un CodeSandbox qui utilise my-first-function de mon API de démonstration. Vous pouvez créer un fork et modifier l'URL de la requête Axios pour tester votre fonction.

CodeSandbox : ma première fonction

CodeSandbox : ma première fonction
( Grand aperçu )

Devenir plus fantaisiste

Envoi d'une réponse de votre API indiquant message: "A ok!" n'est pas vraiment excitant, donc dans le prochain bit, je vais vous montrer comment interroger l'API GitHub REST et créer une carte de profil personnelle à afficher sur votre propre site en utilisant l'API que vous venez de créer, et cela ressemblera un peu à ceci .

CodeSandbox : carte de profil de démonstration

CodeSandbox : carte de profil de démonstration
( Grand aperçu )

Dépendances

Pour utiliser l'API GitHub REST, vous devez installer le package @octokit/rest.

 npm install @octokit/rest

Obtenir l'utilisateur brut de GitHub

Ajoutez ce qui suit à src/api/get-github-user-raw.js .

 // src/api/get-github-user-raw.js import { Octokit } from '@octokit/rest'; const octokit = new Octokit({ auth: process.env.OCTOKIT_PERSONAL_ACCESS_TOKEN }); export default async function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); try { const { data } = await octokit.request(`GET /users/{username}`, { username: 'PaulieScanlon' }); res.status(200).json({ message: 'A ok!', user: data }); } catch (error) { res.status(500).json({ message: 'Error!' }); } }

Jeton d'accès

Pour communiquer avec l'API GitHub REST, vous aurez besoin d'un jeton d'accès. Vous pouvez l'obtenir en suivant les étapes de ce guide de GitHub : Création d'un jeton d'accès personnel.

Variables .env

Pour sécuriser votre jeton d'accès, ajoutez ce qui suit à .env.development et .env.production .

 OCTOKIT_PERSONAL_ACCESS_TOKEN=123YourAccessTokenABC

Vous pouvez en savoir plus sur les variables d'environnement Gatsby dans ce guide de Gatsby : Variables d'environnement.

Démarrer le serveur de développement

Comme vous l'avez fait auparavant, démarrez le serveur de développement Gatsby en tapant ce qui suit dans votre terminal.

 npm run develop

Faire une demande depuis le navigateur

Avec le serveur de développement Gatsby en cours d'exécution, vous pouvez visiter http://localhost:8000/api/get-github-user-raw, et comme il s'agit également d'une simple requête GET , vous devriez voir ce qui suit dans votre navigateur. ( J'ai supprimé une partie de la réponse par souci de brièveté. )

 { "message": "A ok!", "user": { "login": "PaulieScanlon", "id": 1465706, "node_id": "MDQ6VXNlcjE0NjU3MDY=", "avatar_url": "https://avatars.githubusercontent.com/u/1465706?v=4", "gravatar_id": "", "url": "https://api.github.com/users/PaulieScanlon", "type": "User", "site_admin": false, "name": "Paul Scanlon", "company": "Paulie Scanlon Ltd.", "blog": "https://www.paulie.dev", "location": "Worthing", "email": "[email protected]", "hireable": true, "bio": "Jamstack Developer / Technical Content Writer (freelance)", "twitter_username": "pauliescanlon", "created_at": "2012-02-23T13:43:26Z", "two_factor_authentication": true, ... } }

Voici un exemple CodeSandbox de la réponse brute complète.

CodeSandbox : réponse brute

CodeSandbox : réponse brute
( Grand aperçu )

Vous verrez d'après ce qui précède qu'il y a beaucoup de données renvoyées dont je n'ai pas vraiment besoin, ce qui suit dépend entièrement de vous car c'est votre API mais j'ai trouvé utile de manipuler un peu la réponse de l'API GitHub avant de le renvoyer à mon code frontal.

Si vous souhaitez faire de même, vous pouvez créer une nouvelle fonction et ajouter ce qui suit à src/api/get-github-user.js .

 // src/api/get-github-user.js import { Octokit } from '@octokit/rest'; const octokit = new Octokit({ auth: process.env.OCTOKIT_PERSONAL_ACCESS_TOKEN }); export default async function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); try { const { data } = await octokit.request(`GET /users/{username}`, { username: 'PaulieScanlon' }); res.status(200).json({ message: 'A ok!', user: { name: data.name, blog_url: data.blog, bio: data.bio, photo: data.avatar_url, githubUsername: `@${data.login}`, githubUrl: data.html_url, twitterUsername: `@${data.twitter_username}`, twitterUrl: `https://twitter.com/${data.twitter_username}` } }); } catch (error) { res.status(500).json({ message: 'Error!' }); } }

Vous verrez d'après ce qui précède qu'au lieu de renvoyer l'objet de données complet renvoyé par l'API GitHub REST, je sélectionne uniquement les bits dont j'ai besoin, les renomme et ajoute quelques bits avant les valeurs de nom d'utilisateur et d'URL. Cela rend la vie un peu plus facile lorsque vous venez de rendre les données dans le code frontal.

Voici un exemple CodeSandbox de la réponse formatée.

CodeSandbox : réponse formatée

CodeSandbox : réponse formatée
( Grand aperçu )

Ceci est très similaire au Profile Card CodeSandbox du précédent, mais j'ai également imprimé les données afin que vous puissiez voir comment chaque élément de données manipulé est utilisé.

Il convient de noter à ce stade que les quatre démos CodeSandbox de ce didacticiel utilisent l'API de démonstration, et qu'aucune d'entre elles n'est construite à l'aide de Gatsby ou hébergée sur Gatsby Cloud - cool ay!

Variables .env dans Gatsby Cloud

Avant de déployer vos deux nouvelles fonctions, vous devrez ajouter le jeton d'accès GitHub à la section des variables d'environnement dans Gatsby Cloud.

Capture d'écran de Gatsby Cloud avec les paramètres du site
( Grand aperçu )

Où aller en partant d'ici?

Je me suis justement posé cette question. En règle générale, les fonctions sans serveur sont utilisées dans les requêtes côté client et, bien que ce soit bien, je me demandais si elles pouvaient également être utilisées au moment de la construction pour "cuire" statiquement des données dans une page plutôt que de s'appuyer sur JavaScript qui peut ou non être désactivé dans l'utilisateur. navigateur.

… alors c'est exactement ce que j'ai fait.

Voici une sorte de tableau de bord de données qui utilise les données renvoyées par les fonctions Gatsby au moment de l'exécution et de la construction. J'ai construit ce site à l'aide d'Astro et l'ai déployé sur GitHub Pages.

La raison pour laquelle je pense que c'est une excellente approche est que je peux réutiliser la même fonctionnalité à la fois sur le serveur et dans le navigateur sans rien dupliquer.

Dans cette version d'Astro, j'ai atteint le même point de terminaison exposé par mon API pour renvoyer des données qui sont ensuite soit intégrées à la page (idéal pour le référencement), soit récupérées au moment de l'exécution par le navigateur (idéal pour afficher des données en direct fraîches ou actualisées) .

Tableau de bord des données

Les données affichées sur la gauche du site sont demandées au moment de la construction et intégrées à la page avec Astro. Les données à droite de la page sont demandées lors de l'exécution à l'aide d'une requête côté client. J'ai utilisé des points de terminaison légèrement différents exposés par l'API GitHub REST pour interroger différents comptes d'utilisateurs GitHub qui créent les différentes listes.

Tableau de bord des données
( Grand aperçu )

Tout ce que vous voyez sur ce site est fourni par mon API plus complète. Je l'ai appelé : Paulie API et je l'utilise pour un certain nombre de mes sites Web.

API Paulie

L'API Paulie, comme l'API de ce didacticiel, est construite avec Gatsby, mais comme Gatsby peut agir à la fois comme un site et comme une API, je l'ai utilisée pour documenter le fonctionnement de toutes mes fonctions et chaque point de terminaison a sa propre page qui peut être utilisée comme un interactif aire de jeux… n'hésitez pas à y faire un tour.

API Paulie
( Grand aperçu )

Donc, voilà, une API Gatsby Functions qui peut être utilisée par n'importe quel code côté client ou côté serveur, à partir de n'importe quel site Web construit avec n'importe quelle pile technologique.

Essayez-le et je serais très intéressé de voir ce que vous construisez. N'hésitez pas à partager dans les commentaires ci-dessous ou venez me trouver sur Twitter : @PaulieScanlon.