Construire une API avec des fonctions Gatsby
Publié: 2022-03-10Vous 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 :
- Le frontal ne pouvait pas prendre en charge les fonctions sans serveur.
- 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.
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 + ».
À 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
.
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
.
Avec votre fournisseur Git connecté, vous pouvez rechercher votre référentiel et donner un nom à votre site.
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.
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
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
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
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
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.
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.
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.
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.