Creazione di un'API con le funzioni Gatsby
Pubblicato: 2022-03-10Probabilmente hai sentito parlare delle funzioni serverless, ma in caso contrario, le funzioni serverless forniscono funzionalità tipicamente associate alle tecnologie lato server che possono essere implementate insieme al codice front-end senza rimanere intrappolati nelle infrastrutture lato server.
Con il codice lato server e lato client che coesistono nella stessa base di codice, gli sviluppatori front-end come me possono estendere la portata di ciò che è possibile utilizzando gli strumenti che già conoscono e amano.
Limitazioni
La coesistenza è ottima, ma ci sono almeno due scenari che ho riscontrato in cui l'utilizzo di funzioni serverless in questo modo non si adattava perfettamente all'attività in questione. Sono i seguenti:
- Il front-end non può supportare le funzioni serverless.
- La stessa funzionalità era richiesta da più front-end.
Per aiutare a fornire un contesto, ecco un esempio di entrambi i punti 1 e 2 sopra menzionati. Gestisco un progetto open source chiamato MDX Embed, vedrai dal sito di documenti che non è un sito Web di Gatsby. È stato creato utilizzando Storybook e Storybook da solo non fornisce funzionalità di funzione serverless. Volevo implementare i contributi "Paga quello che vuoi" per aiutare a finanziare questo progetto e volevo usare Stripe per abilitare pagamenti sicuri ma senza un "back-end" sicuro Ciò non sarebbe stato possibile.
Astraendo questa funzionalità in un'API creata con Gatsby Functions, sono stato in grado di ottenere ciò che volevo con MDX Embed e anche riutilizzare la stessa funzionalità e abilitare la funzionalità "Paga quello che vuoi" per il mio blog.
Puoi leggere di più su come l'ho fatto qui: Monetizza il software open source con le funzioni Gatsby e Stripe.
È a questo punto che l'utilizzo di Gatsby Functions può agire come una sorta di Back-end per il front-end o BFF e lo sviluppo in questo modo è più simile allo sviluppo di un'API ( Application Programming Interface ).
Le API vengono utilizzate dal codice front-end per gestire cose come accessi, recupero di dati in tempo reale o attività sicure che non sono adeguatamente gestite dal solo browser. In questo tutorial, spiegherò come creare un'API utilizzando Gatsby Functions e distribuirla su Gatsby Cloud.
Controlli preliminari
Le funzioni Gatsby funzionano quando vengono distribuite su Gatsby Cloud o Netlify e in questo tutorial spiegherò come distribuire su Gatsby Cloud, quindi dovrai prima registrarti e creare un account gratuito.
Avrai anche bisogno di un account GitHub, GitLab o BitBucket, è così che Gatsby Cloud legge il tuo codice e quindi crea il tuo "sito" o, in questo caso, l'API.
Ai fini di questo tutorial, userò GitHub. Se preferisci andare avanti, il codice API demo finito può essere trovato sul mio GitHub.
Iniziare
Crea una nuova directory da qualche parte sul tuo disco locale ed esegui quanto segue nel tuo terminale. Questo imposterà un package.json
predefinito.json .
npm init -y
Dipendenze
Digita quanto segue nel tuo terminale per installare le dipendenze richieste.
npm install gatsby react react-dom
Pagine
È probabile che la tua API non disponga di "pagine", ma per evitare di visualizzare l' avviso di pagina mancante predefinito di Gatsby quando visiti l'URL radice nel browser, aggiungi quanto segue sia a src/pages/index.js
che a src/pages/404.js
.
//src/pages/index.js & src/pages/404.js export default () => null;
API
Aggiungi quanto segue a src/api/my-first-function.js
.
Spiegherò un po 'più tardi cosa significa 'Access-Control-Allow-Origin', '*'
, ma in breve, assicura che le tue API di altre origini non siano bloccate da 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!' }); }
Script
Aggiungi quanto segue a package.json
.
//package.json ... "scripts": { "develop": "gatsby develop", "build": "gatsby build" }, ...
Avvia il server di sviluppo Gatsby
Per avviare il server di sviluppo Gatsby, esegui quanto segue nel tuo terminale.
npm run develop
Fai una richiesta dal browser
Con il server di sviluppo di Gatsby in esecuzione, puoi visitare http://localhost:8000/api/my-first-function e, poiché si tratta di una semplice richiesta GET
, dovresti vedere quanto segue nel tuo browser.
{ "message": "A ok!" }
Congratulazioni
Hai appena sviluppato un'API utilizzando Gatsby Functions.
Distribuire
Se vedi la risposta di cui sopra nel tuo browser, è lecito ritenere che la tua funzione funzioni correttamente in locale, nei passaggi seguenti spiegherò come distribuire la tua API su Gatsby Cloud e accedervi utilizzando una richiesta HTTP
da CodeSandbox.
Spingere il codice per Git
Prima di tentare di eseguire la distribuzione su Gatsby Cloud, devi aver inviato il codice al provider Git di tua scelta.
Gatsby Nuvola
Accedi al tuo account Gatsby Cloud e cerca il grande pulsante viola che dice "Aggiungi sito +".
Nel passaggio successivo, ti verrà chiesto di importare da un repository Git o Avvia da un modello, selezionare Import from Git Repository
e premere next
.
Come accennato in precedenza, Gatsby Cloud può connettersi a GitHub, GitLab o Bitbucket. Seleziona il tuo provider Git preferito e premi next
.
Con il tuo provider Git connesso, puoi cercare il tuo repository e dare un nome al tuo sito.
Dopo aver selezionato il tuo repository e chiamato il tuo sito, clicca su next
.
Puoi saltare "Integrazioni" e "Installazione" poiché non ne avremo bisogno.
Se tutto è andato come previsto, dovresti vedere qualcosa di simile allo screenshot qui sotto.
Vedrai vicino alla parte superiore sul lato sinistro dello schermo un URL che termina con gatsbyjs.io
, questo sarà l'URL per la tua API e tutte le funzioni che crei sono accessibili aggiungendo /api/name-of-function
alla fine di questo URL.
Ad esempio, la versione distribuita completa di my-first-function.js
per la mia API demo è la seguente:
API demo: la mia prima funzione .
Testare la tua API
Visitare l'URL della tua API è una cosa, ma non è proprio il modo in cui le API vengono generalmente utilizzate. Idealmente per testare la tua API devi fare una richiesta alla funzione da un'origine completamente non correlata.
È qui che res.setHeader('Access-Control-Allow-Origin', '*');
viene in soccorso. Anche se non è sempre desiderabile consentire a qualsiasi dominio (sito web) di accedere alle tue funzioni, per la maggior parte, le funzioni pubbliche sono proprio questo, pubbliche. L'impostazione dell'intestazione del controllo di accesso su un valore di *
significa che qualsiasi dominio può accedere alla tua funzione, senza questo, qualsiasi dominio diverso dal dominio su cui è ospitata l'API verrà bloccato da CORS.
Ecco un CodeSandbox che utilizza my-first-function
dalla mia API demo. Puoi eseguire il fork di questo e modificare l'URL della richiesta Axios per testare la tua funzione.
CodeSandbox: la mia prima funzione
Diventando più elaborato
Invio di una risposta dalla tua API che dice message: "A ok!"
non è esattamente eccitante, quindi nel prossimo bit ti mostrerò come interrogare l'API REST di GitHub e creare una scheda del profilo personale da visualizzare sul tuo sito utilizzando l'API che hai appena creato, e sarà un po' così .
CodeSandbox: scheda profilo demo
Dipendenze
Per utilizzare l'API REST di GitHub dovrai installare il pacchetto @octokit/rest.
npm install @octokit/rest
Ottieni GitHub User Raw
Aggiungi quanto segue a 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!' }); } }
Token di accesso
Per comunicare con l'API REST di GitHub avrai bisogno di un token di accesso. Puoi ottenerlo seguendo i passaggi in questa guida da GitHub: Creazione di un token di accesso personale.
.env
variabili
Per mantenere sicuro il tuo token di accesso, aggiungi quanto segue a .env.development
e .env.production
.
OCTOKIT_PERSONAL_ACCESS_TOKEN=123YourAccessTokenABC
Puoi leggere di più sulle variabili di ambiente di Gatsby in questa guida da Gatsby: Variabili di ambiente.
Avvia server di sviluppo
Come hai fatto prima, avvia il server di sviluppo Gatsby digitando quanto segue nel tuo terminale.
npm run develop
Fai una richiesta dal browser
Con il server di sviluppo Gatsby in esecuzione, puoi visitare http://localhost:8000/api/get-github-user-raw e, poiché anche questa è una semplice richiesta GET
, dovresti vedere quanto segue nel tuo browser. ( Ho rimosso parte della risposta per brevità. )
{ "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, ... } }
Ecco un esempio CodeSandbox della risposta grezza completa.
CodeSandbox: risposta grezza
Vedrai da quanto sopra che sono stati restituiti molti dati di cui non ho davvero bisogno, il prossimo bit dipende completamente da te in quanto è la tua API ma ho trovato utile manipolare un po' la risposta dell'API GitHub prima di rispedirlo al mio codice frontend.
Se desideri fare lo stesso, puoi creare una nuova funzione e aggiungere quanto segue a 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!' }); } }
Vedrai da quanto sopra che, anziché restituire l'oggetto dati completo restituito dall'API REST di GitHub, scelgo solo i bit di cui ho bisogno, li rinomino e aggiungo alcuni bit prima dei valori del nome utente e dell'URL. Questo rende la vita un po' più facile quando si tratta di eseguire il rendering dei dati nel codice frontend.
Ecco un esempio CodeSandbox della risposta formattata.
CodeSandbox: risposta formattata
Questo è molto simile al Profile Card CodeSandbox di prima, ma ho anche stampato i dati in modo da poter vedere come viene utilizzato ogni elemento di dati manipolato.
Vale la pena notare a questo punto che tutte e quattro le demo di CodeSandbox in questo tutorial utilizzano l'API demo e nessuna di esse è stata creata utilizzando Gatsby o ospitata su Gatsby Cloud — fantastico ay!
Variabili .env
in Gatsby Cloud
Prima di distribuire le tue due nuove funzioni, dovrai aggiungere il token GitHub Access alla sezione delle variabili di ambiente in Gatsby Cloud.
Dove andare da qui?
Mi sono posto proprio questa domanda. In genere, le funzioni serverless vengono utilizzate nelle richieste lato client e, sebbene vada bene, mi chiedevo se potessero essere utilizzate anche in fase di compilazione per "infornare" staticamente i dati in una pagina piuttosto che fare affidamento su JavaScript che può o non può essere disabilitato nell'utente browser.
...quindi è esattamente quello che ho fatto.
Ecco una sorta di dashboard di dati che utilizza i dati restituiti da Gatsby Functions sia in fase di esecuzione che in fase di compilazione. Ho creato questo sito utilizzando Astro e l'ho distribuito GitHub Pages.
Il motivo per cui penso che questo sia un ottimo approccio è perché sono in grado di riutilizzare la stessa funzionalità sia sul server che nel browser senza duplicare nulla.
In questa build di Astro ho raggiunto lo stesso endpoint esposto dalla mia API per restituire i dati che vengono poi inseriti nella pagina (ottimo per SEO) o recuperati in fase di esecuzione dal browser (ottimo per mostrare dati aggiornati o aggiornati al minuto) .
Cruscotto dati
I dati visualizzati a sinistra del sito sono richiesti in fase di compilazione e inseriti nella pagina con Astro. I dati a destra della pagina vengono richiesti in fase di esecuzione tramite una richiesta lato client. Ho utilizzato endpoint leggermente diversi esposti dall'API REST di GitHub per eseguire query su account utente GitHub diversi che creano elenchi diversi.
Tutto ciò che vedi su questo sito è fornito dalla mia API più completa. L'ho chiamato: API Paulie e lo uso per molti dei miei siti web.
API Paulie
L'API Paulie come l'API di questo tutorial è costruita con Gatsby ma poiché Gatsby può fungere sia da sito che da API, l'ho usata per documentare come funzionano tutte le mie funzioni e ogni endpoint ha la sua pagina che può essere utilizzata come un'interfaccia interattiva parco giochi... sentiti libero di dare un'occhiata in giro.
Quindi, ecco qua, un'API Gatsby Functions che può essere utilizzata da qualsiasi codice lato client o lato server, da qualsiasi sito Web creato con qualsiasi stack tecnologico.
Provalo e sarei molto interessato a vedere cosa costruisci. Sentiti libero di condividere nei commenti qui sotto o vieni a trovarmi su Twitter: @PaulieScanlon.