Construirea unui API cu funcții Gatsby

Publicat: 2022-03-10
Rezumat rapid ↬ În acest tutorial, Paul Scanlon explică cum să construiți un API utilizând Funcțiile Gatsby și ce trebuie să aveți în vedere atunci când îl implementați în Gatsby Cloud.

Probabil ați auzit despre Funcțiile Serverless, dar dacă nu ați auzit, Funcțiile Serverless oferă funcționalități asociate în mod obișnuit cu tehnologiile server-side care pot fi implementate împreună cu codul front-end fără a fi prins în infrastructurile server-side.

Având în vedere că codul serverului și cel al clientului coexistă în aceeași bază de cod, dezvoltatorii front-end ca mine pot extinde raza de acțiune a ceea ce este posibil folosind instrumentele pe care deja le cunosc și le iubesc.

Limitări

Coexistența este grozavă, dar există cel puțin două scenarii pe care le-am întâlnit în care utilizarea Funcțiilor Serverless în acest fel nu era potrivită pentru sarcina în cauză. Acestea sunt după cum urmează:

  1. Partea frontală nu a putut suporta funcții fără server.
  2. Aceeași funcționalitate a fost cerută de mai mult de un front end.

Pentru a ajuta la furnizarea unui context, iată un exemplu de puncte 1 și 2 numite mai sus. Mențin un proiect Open-source numit MDX Embed, veți vedea de pe site-ul de documente că nu este un site Gatsby. A fost construit folosind Storybook și Storybook singur nu oferă capabilități Serverless Function. Am vrut să implementez contribuții „Plătește ce vrei” pentru a ajuta la finanțarea acestui proiect și am vrut să folosesc Stripe pentru a permite plăți sigure, dar fără un „backend” sigur. Acest lucru nu ar fi fost posibil.

Abstragând această funcționalitate într-un API construit cu Funcțiile Gatsby, am reușit să obțin ceea ce îmi doream cu MDX Embed și, de asemenea, să reutilizam aceeași funcționalitate și să activez funcționalitatea „Plătește ce vrei” pentru blogul meu.

Puteți citi mai multe despre cum am făcut asta aici: Monetizați software-ul open-source cu funcții Gatsby și Stripe.

În acest moment, folosirea Funcțiilor Gatsby poate acționa ca un fel de back-end pentru front-end sau BFF și dezvoltarea în acest fel este mai asemănătoare cu dezvoltarea unui API ( Application Programming Interface ).

API-urile sunt folosite de codul front-end pentru a gestiona lucruri precum autentificare, preluarea datelor în timp real sau sarcini securizate care nu sunt gestionate în mod adecvat doar de browser. În acest tutorial, voi explica cum să construiți un API folosind funcțiile Gatsby și să îl implementez în Gatsby Cloud.

Mai multe după săritură! Continuați să citiți mai jos ↓

Verificări înainte de zbor

Funcțiile Gatsby funcționează atunci când sunt implementate în Gatsby Cloud sau Netlify, iar în acest tutorial, voi explica cum să implementați în Gatsby Cloud, așa că va trebui mai întâi să vă înregistrați și să creați un cont gratuit.

De asemenea, veți avea nevoie fie de un cont GitHub, GitLab sau BitBucket, astfel Gatsby Cloud vă citește codul și apoi vă construiește „site-ul” sau, în acest caz, API.

În scopul acestui tutorial, voi folosi GitHub. Dacă preferați să treceți mai departe, codul API demonstrativ finalizat poate fi găsit pe GitHub-ul meu.

Noțiuni de bază

Creați un director nou undeva pe unitatea dvs. locală și executați următoarele în terminal. Acest lucru va configura un package.json implicit.

 npm init -y

Dependente

Introduceți următoarele în terminalul dvs. pentru a instala dependențele necesare.

 npm install gatsby react react-dom

Pagini

Este posibil ca API-ul dvs. să nu aibă nicio „pagină”, dar pentru a evita să vedeți avertismentul implicit de pagină lipsă al lui Gatsby atunci când vizitați adresa URL rădăcină în browser, adăugați următoarele atât la src/pages/index.js , cât și la src/pages/404.js .

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

API

Adăugați următoarele la src/api/my-first-function.js .

Voi explica puțin mai târziu ce înseamnă 'Access-Control-Allow-Origin', '*' , dar pe scurt, se asigură că API-urile tale din alte origini nu sunt blocate de 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!' }); }

Scripturi

Adăugați următoarele la package.json .

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

Porniți serverul de dezvoltare Gatsby

Pentru a porni serverul de dezvoltare Gatsby, rulați următoarele în terminalul dvs.

 npm run develop

Faceți o solicitare din browser

Cu serverul de dezvoltare al lui Gatsby rulând, puteți vizita http://localhost:8000/api/my-first-function și, deoarece aceasta este o simplă solicitare GET , ar trebui să vedeți următoarele în browser.

 { "message": "A ok!" }

Felicitări

Tocmai ați dezvoltat un API folosind funcțiile Gatsby.

Implementează

Dacă vedeți răspunsul de mai sus în browser, este sigur să presupuneți că funcția dumneavoastră funcționează corect la nivel local, în următorii pași voi explica cum să vă implementați API-ul pe Gatsby Cloud și să îl accesați folosind o solicitare HTTP de la CodeSandbox.

Împingeți codul în Git

Înainte de a încerca să implementați în Gatsby Cloud, va trebui să fi trimis codul către furnizorul dvs. Git ales.

Gatsby Cloud

Conectați-vă la contul dvs. Gatsby Cloud și căutați butonul mare violet care spune „Adăugați site +”.

Captură de ecran a site-ului Gatsby Cloud Add
Adăugați un site la Gatsby Cloud. (Previzualizare mare)

În pasul următor, vi se va cere fie să importați dintr-un depozit Git, fie să începeți dintr-un șablon, selectați Import from Git Repository și apăsați next .

Importarea selectării capturii de ecran dintr-un depozit Git
Selectați import dintr-un depozit Git. (Previzualizare mare)

După cum sa menționat mai sus, Gatsby Cloud se poate conecta fie la GitHub, GitLab sau Bitbucket. Selectați furnizorul dvs. Git preferat și apăsați next .

Captură de ecran cu selecția furnizorului Gatsby Cloud Git
Selectați de la furnizorul dvs. Git preferat. (Previzualizare mare)

Cu furnizorul dvs. Git conectat, puteți căuta depozitul dvs. și puteți da un nume site-ului.

Captură de ecran a căutării Gatsby Cloud pentru site de la furnizorul Git
Căutați site-ul dvs. de la furnizorul dvs. Git. (Previzualizare mare)

După ce v-ați selectat depozitul și ați numit site-ul, apăsați next .

Puteți sări peste „Integrații” și „Configurare”, deoarece nu vom avea nevoie de acestea.

Dacă totul a mers conform planului, ar trebui să vedeți ceva similar cu captura de ecran de mai jos.

Captură de ecran a site-ului implementat cu succes
„site” construit și implementat cu succes pe Gatsby Cloud. (Previzualizare mare)

Veți vedea în partea de sus, în partea stângă a ecranului, o adresă URL care se termină cu gatsbyjs.io , aceasta va fi adresa URL pentru API-ul dvs. și orice funcții pe care le creați pot fi accesate adăugând /api/name-of-function până la sfârșitul acestei adrese URL.

De exemplu, versiunea completă implementată a my-first-function.js pentru API-ul meu demo este după cum urmează:

Demo API: Prima mea funcție .

Testarea API-ului dvs

Vizitarea adresei URL a API-ului dvs. este un lucru, dar nu este chiar modul în care sunt utilizate de obicei API-urile. În mod ideal, pentru a vă testa API-ul, trebuie să faceți o solicitare funcției dintr-o origine complet fără legătură.

Aici este res.setHeader('Access-Control-Allow-Origin', '*'); vine în ajutor. Deși nu este întotdeauna de dorit să permiteți oricărui domeniu (site web) să vă acceseze funcțiile, în cea mai mare parte, funcțiile publice sunt doar atât, publice. Setarea antetului Access Control la o valoare * înseamnă că orice domeniu vă poate accesa funcția, fără aceasta, orice domeniu, altul decât domeniul pe care este găzduit API-ul, va fi blocat de CORS.

Iată un CodeSandbox care folosește my-first-function din API-ul meu demo. Puteți să bifurcați acest lucru și să schimbați adresa URL a solicitării Axios pentru a vă testa funcția.

CodeSandbox: Prima mea funcție

CodeSandbox: Prima mea funcție
(Previzualizare mare)

Devenind mai scump

Se trimite un răspuns de la API-ul dvs. care spune message: "A ok!" nu este tocmai interesant, așa că în următorul fragment vă voi arăta cum să interogați API-ul REST GitHub și să faceți un card de profil personal pentru a-l afișa pe propriul site folosind API-ul pe care tocmai l-ați creat și va arăta puțin așa .

CodeSandbox: card de profil demonstrativ

CodeSandbox: card de profil demonstrativ
(Previzualizare mare)

Dependente

Pentru a utiliza API-ul REST GitHub, va trebui să instalați pachetul @octokit/rest.

 npm install @octokit/rest

Obțineți GitHub User Raw

Adăugați următoarele la 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 de acces

Pentru a comunica cu API-ul REST GitHub, veți avea nevoie de un token de acces. Puteți obține acest lucru urmând pașii din acest ghid din GitHub: Crearea unui simbol de acces personal.

.env Variabile

Pentru a vă menține în siguranță indicativul de acces, adăugați următoarele la .env.development și .env.production .

 OCTOKIT_PERSONAL_ACCESS_TOKEN=123YourAccessTokenABC

Puteți citi mai multe despre variabilele de mediu Gatsby în acest ghid din Gatsby: Variabile de mediu.

Porniți Development Server

Așa cum ați făcut înainte, porniți serverul de dezvoltare Gatsby tastând următoarele în terminal.

 npm run develop

Faceți o solicitare din browser

Cu serverul de dezvoltare Gatsby care rulează, puteți vizita http://localhost:8000/api/get-github-user-raw și, deoarece și aceasta este o simplă solicitare GET , ar trebui să vedeți următoarele în browser. ( Am eliminat o parte din răspuns pentru concizie. )

 { "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, ... } }

Iată un exemplu CodeSandbox al răspunsului brut complet.

CodeSandbox: Răspuns brut

CodeSandbox: Răspuns brut
(Previzualizare mare)

Veți vedea din cele de mai sus că s-au returnat destul de multe date de care nu prea am nevoie, următorul bit depinde în totalitate de dvs., deoarece este API-ul dvs., dar mi s-a părut util să manipulez puțin răspunsul API-ului GitHub înainte de a-l trimite înapoi la codul meu frontend.

Dacă doriți să faceți același lucru, puteți crea o nouă funcție și adăugați următoarele la 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!' }); } }

Veți vedea din cele de mai sus că, în loc să returnez obiectul de date complet returnat de API-ul REST GitHub, aleg doar biții de care am nevoie, îi redenumesc și adaug câțiva biți înaintea numelui de utilizator și a valorilor URL. Acest lucru face viața puțin mai ușoară atunci când veniți să redați datele în codul frontend.

Iată un exemplu CodeSandbox al răspunsului formatat.

CodeSandbox: Răspuns formatat

CodeSandbox: Răspuns formatat
(Previzualizare mare)

Acesta este foarte asemănător cu Codul de nisip pentru card de profil de mai devreme, dar am tipărit și datele, astfel încât să puteți vedea cum este utilizat fiecare element de date manipulat.

În acest moment, merită remarcat faptul că toate cele patru demo-uri CodeSandbox din acest tutorial folosesc API-ul demo și niciunul dintre ele nu este construit folosind Gatsby sau găzduit pe Gatsby Cloud - cool ay!

Variabile .env în Gatsby Cloud

Înainte de a vă implementa cele două noi funcții, va trebui să adăugați jetonul de acces GitHub la secțiunea variabile de mediu din Gatsby Cloud.

Captură de ecran a lui Gatsby Cloud cu setările site-ului
(Previzualizare mare)

Unde să mergi de aici?

Mi-am pus chiar această întrebare. În mod obișnuit, funcțiile fără server sunt utilizate în solicitările de la partea clientului și, deși este în regulă, m-am întrebat dacă ar putea fi utilizate și în timpul construirii pentru a „coa” datele într-o pagină, în loc să se bazeze pe JavaScript, care poate fi sau nu dezactivat în utilizatorul. browser.

...deci exact asta am făcut.

Iată un fel de tablou de bord de date care utilizează datele returnate de Gatsby Functions atât în ​​timpul rulării, cât și în timpul construirii. Am construit acest site folosind Astro și l-am implementat GitHub Pages.

Motivul pentru care cred că aceasta este o abordare excelentă este că pot reutiliza aceeași funcționalitate atât pe server, cât și în browser, fără a duplica nimic.

În această versiune Astro, am lovit același punct final expus de API-ul meu pentru a returna date care apoi sunt fie incluse în pagină (excelent pentru SEO) fie preluate în timpul rulării de către browser (excelent pentru a afișa date actuale proaspete sau actualizate la minut) .

Tabloul de bord de date

Datele afișate în partea stângă a site-ului sunt solicitate în timpul construirii și incluse în pagina cu Astro. Datele din dreapta paginii sunt solicitate în timpul execuției folosind o solicitare pe partea clientului. Am folosit puncte finale ușor diferite expuse de API-ul REST GitHub pentru a interoga diferite conturi de utilizator GitHub care creează diferite liste.

Tabloul de bord de date
(Previzualizare mare)

Tot ceea ce vedeți pe acest site este furnizat de API-ul meu mai complet. L-am numit: Paulie API și îl folosesc pentru o serie de site-uri web.

Paulie API

API-ul Paulie, la fel ca API-ul din acest tutorial, este construit cu Gatsby, dar deoarece Gatsby poate acționa atât ca site, cât și ca API, l-am folosit pentru a documenta modul în care funcționează toate funcțiile mele și fiecare punct final are propria pagină care poate fi folosită ca un interactiv. loc de joacă... nu ezitați să aruncați o privire în jur.

Paulie API
(Previzualizare mare)

Așadar, iată-l, Un Gatsby Functions API care poate fi folosit de orice cod de la partea clientului sau de pe partea serverului, de pe orice site web construit cu orice stivă tehnologică.

Încearcă-l și aș fi foarte interesat să văd ce construiești. Simțiți-vă liber să distribuiți în comentariile de mai jos sau veniți să mă găsiți pe Twitter: @PaulieScanlon.