Monetizați software-ul open-source cu funcții Gatsby și Stripe
Publicat: 2022-03-10În acest articol, voi explica cum am folosit Funcțiile Gatsby și API-ul Stripe pentru a activa contribuțiile securizate „Plătește ceea ce vrei” care ajută la finanțarea proiectului meu open-source MDX Embed.
Notă : MDX Embed vă permite să încorporați cu ușurință conținut media popular de la terți, cum ar fi videoclipuri YouTube, Tweeturi, postări Instagram, lecții Egghead, Spotify, TikTok și multe altele direct în .mdx
- nu este nevoie de import.
Funcții fără server Gatsby
Funcțiile Gatsby deschid o lume cu totul nouă pentru dezvoltatorii front-end, deoarece oferă o modalitate de a scrie și de a utiliza codul de pe partea serverului fără bătaia de cap de a întreține un server. Utilizările pentru Funcțiile Serverless variază de la înscrieri la buletine informative cu ConvertKit, trimiterea unui e-mail utilizând SendGrid, salvarea datelor într-o bază de date precum Fauna sau, în acest caz, acceptarea plăților securizate folosind Stripe - lista este, sincer, nesfârșită!
Serviciile de la terți, cum ar fi cele menționate mai sus, vor accepta numai cererile care sunt trimise pe partea serverului. Există o serie de motive pentru acest lucru, dar utilizarea cheilor securizate sau private este de obicei unul. Folosirea acestor taste pe partea serverului înseamnă că nu sunt expuse clientului (browserului) și nu pot fi abuzate, iar aici funcțiile fără server ale lui Gatsby vă pot ajuta.
Gatsby oferă aceeași abordare logică a funcțiilor fără server ca și în cazul paginilor. De exemplu, paginile site-ului web sunt localizate în src/pages
, iar Funcțiile Serverless sunt localizate în src/api
.
Desigur, există puțin mai mult decât atât, dar experiența de dezvoltator a lui Gatsby este atât logică, cât și consecventă, iar eu îmi place absolut asta!
Funcții de aceeași origine
De nouă ori din zece când lucrați cu Funcții Serverless, le veți folosi așa cum ar fi trebuit să fie folosite, de exemplu, site-ul dvs. folosește propriile funcții. Eu numesc această utilizare Funcții de aceeași origine sau SOF pe scurt. În acest scenariu, atât front-end-ul, cât și API-ul sunt implementate la aceeași origine, de exemplu, www.my-website.com și www.my-website.com/api, iar comunicarea între cele două este fără întreruperi și, desigur , fulgerător de repede!
Iată o diagramă pentru a ilustra cum arată:
Funcții cu origini încrucișate
Există, totuși, cel puțin două scenarii pe care le-am întâlnit în care am avut nevoie de ceea ce am numit „Funcții de origine încrucișată” (sau COF-uri pe scurt). Cele două scenarii în care am avut nevoie de COF-uri sunt următoarele:
- Am nevoie de capabilități pe server, dar site-ul web de origine nu poate rula Funcții Serverless.
- Funcția Serverless este utilizată de mai multe origini.
Notă : Utilizarea lui Gatsby nu este singura modalitate de a scrie Funcții fără server, ci mai multe despre asta într-un moment.
Am experimentat pentru prima dată această abordare în noiembrie 2020, înainte de lansarea Gatsby Functions și am folosit Netlify Functions pentru a furniza comunicații de la server la server cu API-ul Twitter și blogul meu Gatsby și portofoliul comercial. Puteți citi despre această abordare aici: Utilizați funcțiile Netlify și Twitter API v2 ca CMS pentru blogul dvs. Gatsby.
După lansarea Gatsby Functions în iunie 2021, am refactorizat cele de mai sus pentru a lucra cu Gatsby Functions și iată puțin mai multe informații despre cum am procedat și de ce: Utilizarea Gatsby Functions ca API abstractă.
Iată o diagramă pentru a ilustra mai bine abordarea generală.
În diagrama de mai sus, website-1.com
este construit cu Gatsby și ar fi putut folosi Funcții Serverless (dar nu) și website-2.com
este construit folosind ceva care nu are capabilități Serverless Function.
Notă : în ambele cazuri, ambii trebuie să utilizeze același serviciu terță parte, așa că este logic să abstractizați această funcționalitate într-un API autonom.
Exemplul de API de sine stătător ( my-api.com
) este, de asemenea, un site Gatsby și are capabilități Serverless Function, dar, mai important, permite site-urilor web din alte origini să-și folosească Funcțiile Serverless.
Știu la ce te gândești: CORS! Ei bine, stai bine. Voi acoperi asta în scurt timp.
Generarea de bani MDX Embed
Aceasta a fost situația în care m-am găsit cu MDX Embed. Site-ul web de documentație pentru acest proiect este construit folosind Storybook. Storybook nu are capabilități fără server, dar chiar aveam nevoie de comunicare de la server la server. Soluția mea? Am creat un API autonom numit Paulie API.
Paulie API
API-ul Paulie (precum exemplul de API autonom menționat mai sus) poate accepta solicitări de la site-uri web de diferite origini și se poate conecta la o serie de servicii terțe diferite, dintre care unul este Stripe.
Pentru a activa plățile Stripe de la MDX Embed, am creat un punct final api/make-stripe-payment
pe API-ul Paulie care poate transmite informațiile relevante din MDX Embed prin propria funcție Serverless și pe API-ul Stripe pentru a crea o „checkout”. Puteți vedea codul src aici.
Odată ce o finalizare a fost creată cu succes, API-ul Stripe returnează o adresă URL. Această adresă URL este transmisă înapoi la MDX Embed, care deschide o nouă fereastră în browser în care „clienții” își pot introduce în siguranță detaliile de plată pe o pagină web Stripe... și boom! Ești plătit!
Iată o diagramă care ilustrează mai bine cum funcționează:
Această abordare este aceeași cu cea menționată mai sus, unde https://mdx-embed.com trimite solicitări către https://paulieapi.gatsbyjs.io care, la rândul său, se conectează la API-ul Stripe folosind comunicarea de la server la server. Dar înainte de a merge prea mult mai departe, merită să explic de ce nu am folosit react-stripe-js
.
react-stripe-js
react-stripe-js
este un set de instrumente pentru client (browser) care vă permite să creați plăți și elemente Stripe în proiectul dvs. React. Cu react-stripe-js puteți configura o metodă pentru a accepta plăți în siguranță, fără a fi nevoie de comunicare pe partea serverului, dar... și există un dar. Am vrut să implementez contribuțiile „Plătește ce vrei”. Dați-mi voie să vă explic.
Iată o captură de ecran a „produsului” MDX Embed pe care l-am configurat în tabloul de bord Stripe. Rețineți că prețul este de 1,00 USD.
Dacă aș fi folosit react-stripe-js pentru a permite plățile, tuturor „clienților” li s-ar cere să plătească aceeași sumă. În acest caz, este doar 1,00 USD și asta nu va plăti facturile, nu-i așa!
Pentru a activa „Plătiți ceea ce doriți” (de exemplu, o sumă nominală aleasă de un „client”), trebuie să vă aprofundați puțin și să utilizați comunicarea de la server la server și să trimiteți această sumă către API-ul Stripe folosind o solicitare HTTP personalizată. Aici folosesc o funcție Gatsby și trec o valoare dinamică care va fi apoi folosită pentru a crea experiența de „checkout” și pentru a suprascrie prețul definit în tabloul de bord Stripe.
Pe MDX Embed, am adăugat un cod HTML <input type="number" />
care le permite „clienților” să stabilească o sumă în loc să plătească o sumă predefinită - dacă toate comerțul electronic ar fi așa!
Iată un mic videoclip pe care l-am realizat, care arată cum funcționează împreună MDX Embed, Paulie API și Stripe API:
Prin transmiterea valorii de intrare de la MDX Embed la API-ul Paulie, care la rândul său se conectează la API-ul Stripe, pot crea o finalizare „dinamică”.
Notă : Acest lucru înseamnă acum că „clienții” pot decide cât valorează proiectul pentru ei și pot stabili o sumă adecvată pentru a contribui.
Aș dori să o menționez pe Benedicte Raae în acest moment, care mi-a arătat prima dată această abordare în timpul fabulosului său curs Funcții de vară . Puteți afla mai multe vizitând codurile Queen Raae. ( Mulțumesc Benedicte, ești cel mai bun! )
Să vorbim despre CORS
În mod implicit, funcțiile Gatsby Serverless nu vor fi blocate de CORS, deoarece front-end-ul și API-ul sunt implementate la aceeași origine. Cu toate acestea, atunci când dezvoltați funcții Cross-Origin, va trebui să vă configurați API-ul astfel încât să accepte solicitări de la origini diferite de cele ale sale.
Iată un fragment de cod pentru a arăta cum mă ocup de CORS în punctul final api/make-stripe-payment
:
// src/api/make-stripe-payment const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY) import Cors from 'cors' const allowedOrigins = [ 'https://www.mdx-embed.com', 'https://paulie.dev', ] const cors = Cors({ origin: (origin, callback) => { if (allowedOrigins.includes(origin)) { callback(null, true) } else { callback(new Error()) } }, }) const runCorsMiddleware = (req, res) => { return new Promise((resolve, reject) => { cors(req, res, (result) => { if (result instanceof Error) { return reject(result) } return resolve(result) }) }) } export default async function handler(req, res) { const { success_url, cancel_url, amount, product } = req.body try { await runCorsMiddleware(req, res) try { const session = await stripe.checkout.sessions.create({ success_url: success_url, cancel_url: cancel_url, payment_method_types: ['card'], line_items: [ { quantity: 1, price_data: { unit_amount: amount * 100, currency: 'usd', product: product, }, }, ], mode: 'payment', }) res.status(200).json({ message: ' Stripe checkout created ok', url: session.url }) } catch (error) { res.status(500).json({ message: ' Stripe checkout error' }) } } catch (error) { res.status(403).json({ message: ' Request blocked by CORS' }) } }
În fragmentul de cod de mai sus, ar trebui să puteți vedea că am definit o serie de allowedOrigins
permise, acestea sunt singurele origini permise să folosească acest punct final. Solicitările din orice altă origine vor primi un cod de stare 403
și un mesaj Request blocked by CORS
.
Această funcție acceptă și o serie de parametri de corp, dintre care unul este amount
pe care „clientul” a decis să o plătească, aceasta este valoarea de la intrarea HTML pe site-ul MDX Embed. Veți observa, de asemenea, parametrul product
, acesta este ID-ul produsului definit în tabloul de bord Stripe și modul în care API-ul Stripe creează adresa URL corectă de „checkout”. Trecerea acestei valori ca parametru de corp, mai degrabă decât codificarea acesteia în funcție, îmi permite să reutilizam acest punct final pentru alte produse Stripe.
Merită sucul strâns?
Am menționat câteva lucruri pe parcurs pentru care am decis să merg pe acest traseu. La urma urmei, poate părea o modalitate mai complicată de a utiliza funcțiile fără server, dar am motivele mele și cred că merită. Iata de ce.
Paulie API este atât un Cross-Origin API, cât și un site de documentare. Desigur, dacă ai de gând să scrii un API, acesta trebuie să fie documentat, nu?
Aici funcționează în favoarea mea să folosesc Gatsby pentru a-mi alimenta API-ul, deoarece, împreună cu capabilitățile Serverless, API-ul Paulie este, de asemenea, un site web Gatsby și, pentru că este de fapt un site web, îl pot umple cu conținut și îl pot face să arate frumos, dar așteptați că sunt mai multe …
Notă: Paulie API este, de asemenea, un loc de joacă interactiv API!
Fiecare funcție are un link Run in browser
. Aceasta vă duce la o pagină de pe site unde puteți interacționa cu funcția. Servește atât ca un teren de testare util în timp ce dezvolt funcția, cât și o modalitate ușoară de a demonstra cum funcționează funcția, documentele sunt bune, documentele interactive sunt mai bune!
De asemenea, folosesc acest API pentru a oferi funcționalități similare pe partea de server pentru celelalte site-uri web ale mele. Aruncă o privire la pagina Despre, unde am documentat care dintre site-urile mele folosesc ce funcții și iată o diagramă pentru a ilustra modul în care toate se reunesc în prezent.
Ar trebui să vedeți din diagrama de mai sus că https://paulie.dev folosește și punctul final Stripe. Am folosit aceeași abordare ca și cu MDX Embed pentru a activa funcționalitatea „Plătește ceea ce vrei”. Este un lucru mic, dar din moment ce punctul final make-stripe-payment
este deja scris și funcționează, îl pot reutiliza și evit duplicarea acestei funcționalități.
Site-ul web https://paulie.dev are, de asemenea, propriile funcții Gatsby Serverless pe care le folosesc pentru a posta reacțiile utilizatorilor la Fauna și pentru a captura înscrieri la Newsletter. Această funcționalitate este unică pentru acest site, așa că nu am rezumat încă. Cu toate acestea, dacă aș dori înscrieri la buletine informative pe https://www.pauliescanlon.io, acesta ar fi punctul în care migrez funcția către API-ul Paulie.
Abstracția
Acesta ar putea părea un pas înapoi pentru a abstractiza funcțiile fără server. La urma urmei, unul dintre cele mai tari lucruri despre devenirea fără server este că atât codul dvs. frontal, cât și cel back-end sunt live în același loc. După cum am arătat, există momente în care abstractizarea are sens - pentru mine oricum.
Cu siguranță beneficiez de pe urma utilizării acestei abordări și intenționez să-mi dezvolt în continuare API-ul pentru a oferi mai multe funcționalități unui număr de propriile mele site-uri web, dar dacă a câștiga bani din sursă deschisă vă interesează și site-ul dvs. nu este creat folosind Gatsby , această abordare poate fi răspunsul pe care îl căutați.
Vrei să începi cu funcțiile Gatsby? Consultați documentele Gatsby Functions pentru a începe!
Lectură suplimentară
Dacă sunteți interesat să aflați mai multe despre Funcțiile Serverless, vă recomand:
- Cartea lui Swizec Teller, „Manual fără server pentru inginerii front-end”
- Cursul lui Benedict Funcții de vară
- … și, desigur, documentația Gatsby
FuncJam
Între 17 august și 30 septembrie, cei de la Gatsby organizează o competiție comunitară cu câteva premii absolut mega de câștigat. Dacă mai ai timp, atunci accesează FuncJam și alătură-te. De asemenea, verifică secțiunea Byte-size a acestei postări de blog; conține videoclipuri utile și link-uri către o serie de exemple de funcții.
Vă mulțumesc pentru lectură și, dacă doriți să discutați despre ceva menționat în acest articol, lăsați un comentariu mai jos sau găsiți-mă pe Twitter.