Zarabiaj na oprogramowaniu Open Source z funkcjami Gatsby i Stripe

Opublikowany: 2022-03-10
Krótkie podsumowanie ↬ Gatsby Functions zapewnia programistom frontonu sposób pisania i używania kodu po stronie serwera bez kłopotów z utrzymaniem serwera. Jeśli interesuje Cię zarabianie na otwartym oprogramowaniu, a Twoja witryna nie jest zbudowana przy użyciu Gatsby, to podejście może być odpowiedzią, której szukałeś.

W tym artykule wyjaśnię, w jaki sposób korzystałem z funkcji Gatsby Functions i interfejsu API Stripe, aby umożliwić bezpieczne wpłaty typu „Płać, co chcesz”, które pomagają finansować mój projekt MDX Embed o otwartym kodzie źródłowym.

Uwaga : MDX Embed umożliwia łatwe osadzanie popularnych treści multimedialnych innych firm, takich jak filmy z YouTube, tweety, posty na Instagramie, lekcje Egghead, Spotify, TikTok i wiele innych bezpośrednio w pliku .mdx — bez konieczności importowania.

Funkcje bezserwerowe Gatsby

Gatsby Functions otwierają zupełnie nowy świat dla programistów front-end, ponieważ zapewniają sposób pisania i używania kodu po stronie serwera bez kłopotów z utrzymaniem serwera. Zastosowania funkcji bezserwerowych obejmują subskrypcje biuletynów za pomocą ConvertKit, wysyłanie wiadomości e-mail za pomocą SendGrid, zapisywanie danych w bazie danych, takiej jak Fauna, lub w tym przypadku akceptowanie bezpiecznych płatności za pomocą Stripe — lista jest, szczerze mówiąc, nieskończona!

Usługi innych firm, takie jak te wymienione powyżej, akceptują tylko żądania wysyłane po stronie serwera. Istnieje wiele przyczyn takiego stanu rzeczy, ale używanie bezpiecznych lub prywatnych kluczy jest zazwyczaj jednym z nich. Korzystanie z tych kluczy po stronie serwera oznacza, że ​​nie są one narażone na działanie klienta (przeglądarki) i nie można ich nadużywać, i tutaj mogą pomóc funkcje bezserwerowe Gatsby'ego.

Gatsby zapewnia takie samo logiczne podejście do funkcji bezserwerowych, jak do stron. Na przykład strony internetowe znajdują się w src/pages a funkcje bezserwerowe znajdują się w src/api .

Oczywiście jest w tym coś więcej, ale doświadczenie programisty Gatsby jest zarówno logiczne, jak i spójne, a ja absolutnie to uwielbiam!

Funkcje tego samego pochodzenia

Dziewięć razy na dziesięć podczas pracy z funkcjami bezserwerowymi będziesz z nich korzystać w sposób, w jaki miały być używane, np. Twoja witryna korzysta z własnych funkcji. Nazywam to użycie Same Origin Functions lub w skrócie SOF. W tym scenariuszu zarówno interfejs, jak i interfejs API są wdrażane w tym samym miejscu pochodzenia, np. www.my-website.com i www.my-website.com/api, a komunikacja między nimi jest zarówno płynna, jak i oczywiście , płonący szybko!

Oto diagram, który pomoże zilustrować, jak to wygląda:

Schemat funkcji tego samego pochodzenia
Witryna Gatsby korzystająca z własnych funkcji bezserwerowych. (duży podgląd)

Funkcje cross-origin

Istnieją jednak co najmniej dwa scenariusze, z którymi się zetknąłem, w których potrzebowałem czegoś, co nazywam „funkcjami krzyżowymi” (lub w skrócie COF). Dwa scenariusze, w których potrzebowałem COF, są następujące:

  1. Potrzebuję funkcji po stronie serwera, ale witryna pochodzenia nie może uruchamiać funkcji bezserwerowych.
  2. Funkcja bezserwerowa jest używana przez więcej niż jedno źródło.

Uwaga : Używanie Gatsby nie jest jedynym sposobem na napisanie funkcji bezserwerowych, ale o tym za chwilę.

Po raz pierwszy eksperymentowałem z tym podejściem w listopadzie 2020 roku przed wydaniem Gatsby Functions i użyłem Netlify Functions do zapewnienia komunikacji między serwerami za pomocą interfejsu API Twittera oraz mojego bloga Gatsby i portfolio komercyjnego. Możesz przeczytać o tym podejściu tutaj: Użyj Netlify Functions i Twitter API v2 jako CMS dla swojego bloga Gatsby.

Po wydaniu Gatsby Functions w czerwcu 2021 r. Zrefaktorowałem powyższe, aby współpracować z Gatsby Functions, a oto trochę więcej informacji o tym, jak to zrobiłem i dlaczego: Używanie Gatsby Functions jako abstrakcyjnego interfejsu API.

Oto diagram, który lepiej zilustruje ogólne podejście.

Schemat funkcji krzyżowego pochodzenia
Dwie witryny internetowe korzystające z funkcji Serverless API Gatsby. (duży podgląd)

Na powyższym schemacie website-1.com jest zbudowana przy użyciu Gatsby i mogła korzystać z funkcji bezserwerowych (ale tego nie robi), a website-2.com jest zbudowana przy użyciu czegoś, co nie ma możliwości funkcji bezserwerowych.

Uwaga : w obu przypadkach oba muszą korzystać z tej samej usługi innej firmy, więc sensowne jest wyodrębnienie tej funkcji w samodzielny interfejs API.

Przykładowy samodzielny interfejs API ( my-api.com ) jest również witryną Gatsby i ma funkcje funkcji bezserwerowych, ale co ważniejsze, umożliwia witrynom z innych źródeł korzystanie z funkcji bezserwerowych.

Wiem, o czym myślisz: CORS! Cóż, siedź spokojnie. Zaraz to omówię.

Więcej po skoku! Kontynuuj czytanie poniżej ↓

Zarabianie na MDX Embed

Taka była sytuacja, w której znalazłem się z MDX Embed. Witryna internetowa dokumentacji tego projektu została zbudowana przy użyciu Storybook. Storybook nie ma możliwości bezserwerowych, ale naprawdę potrzebowałem komunikacji między serwerami. Moje rozwiązanie? Stworzyłem samodzielne API o nazwie Paulie API.

Paulie API

Paulie API (tak jak wspomniany powyżej przykład samodzielnego API) może akceptować żądania ze stron internetowych o różnym pochodzeniu i może łączyć się z wieloma różnymi usługami stron trzecich, z których jedną jest Stripe.

Aby umożliwić płatności Stripe z MDX Embed, stworzyłem punkt końcowy api/make-stripe-payment w API Paulie, który może przekazywać odpowiednie informacje z MDX Embed za pośrednictwem własnej funkcji Serverless i dalej do API Stripe, aby utworzyć „kasę”. Możesz zobaczyć kod src tutaj.

Po pomyślnym utworzeniu kasy interfejs API Stripe zwraca adres URL. Ten adres URL jest przekazywany z powrotem do MDX Embed, który otwiera nowe okno w przeglądarce, w którym „klienci” mogą bezpiecznie wprowadzić swoje dane dotyczące płatności na stronie internetowej Stripe… i bum! Otrzymujesz wypłatę!

Oto diagram, który lepiej ilustruje, jak to działa:

Schemat osadzania MDX przy użyciu interfejsu API Paulie
MDX Embed łączy się z API Stripe za pośrednictwem funkcji Serverless API Paulie. (duży podgląd)

To podejście jest takie samo, jak wspomniane powyżej, gdzie https://mdx-embed.com wysyła żądania do https://paulieapi.gatsbyjs.io, który z kolei łączy się z API Stripe za pomocą komunikacji serwer-serwer. Ale zanim przejdziemy za dużo dalej, warto wyjaśnić, dlaczego nie użyłem react-stripe-js .

react-stripe-js

React react-stripe-js to zestaw narzędzi po stronie klienta (przeglądarki), który umożliwia tworzenie kas i elementów Stripe w projekcie React. Dzięki React-stripe-js możesz skonfigurować metodę bezpiecznego akceptowania płatności bez potrzeby komunikacji po stronie serwera, ale… i jest ale. Chciałem wdrożyć składki „Płać ile chcesz”. Pozwólcie, że wyjaśnię.

Oto zrzut ekranu „produktu” MDX Embed, który skonfigurowałem na moim pulpicie nawigacyjnym Stripe. Zauważ, że cena wynosi 1,00 USD.

Zrzut ekranu pulpitu nawigacyjnego Stripe z ceną 1,00 USD za produkt MDX Embed
Sekcja produktu w desce rozdzielczej Strip. (duży podgląd)

Gdybym użył React-stripe-js, aby umożliwić płatności, wszyscy „klienci” zostaliby poproszeni o zapłacenie tej samej kwoty. W tym przypadku to tylko 1,00 USD, a to nie zapłaci rachunków, prawda!

Aby włączyć opcję „Płać ile chcesz” (np. nominalną kwotę wybraną przez „klienta”), musisz zanurkować nieco głębiej i użyć komunikacji serwer-serwer i wysłać tę kwotę do API Stripe za pomocą niestandardowego żądania HTTP. W tym miejscu używam funkcji Gatsby i przekazuję dynamiczną wartość, która zostanie następnie wykorzystana do stworzenia doświadczenia „kasy” i zastąpienia ceny określonej w moim panelu Stripe.

W MDX Embed dodałem HTML <input type="number" /> , który pozwala „klientom” ustawić kwotę zamiast płacić z góry określoną kwotę — gdyby tylko wszystkie e-commerce były takie!

Oto krótki film, który zrobiłem, pokazujący, jak MDX Embed, Paulie API i Stripe API współpracują ze sobą:

Jak MDX Embed, Paulie API i Stripe API współpracują ze sobą, aby umożliwić „Płać ile chcesz”.

Przekazując wartość wejściową z MDX Embed do Paulie API, który z kolei łączy się z API Stripe, jestem w stanie stworzyć „dynamiczną” kasę.

Uwaga : oznacza to teraz, że „klienci” mogą decydować, ile projekt jest dla nich wart i ustalać odpowiednią kwotę wkładu.

W tym miejscu chciałbym wspomnieć o Benedicte Raae, która jako pierwsza pokazała mi to podejście podczas swojego bajecznego kursu Summer Functions . Możesz dowiedzieć się więcej, odwiedzając Queen Raae Codes. ( Dzięki Benedicte, jesteś najlepsza! )

Porozmawiajmy o CORS

Domyślnie funkcje bezserwerowe Gatsby nie będą blokowane przez mechanizm CORS, ponieważ interfejs i interfejs API są wdrażane w tym samym miejscu pochodzenia. Jednak podczas opracowywania funkcji Cross-Origin Functions musisz skonfigurować interfejs API, aby akceptował żądania z innego źródła niż jego własne.

Oto fragment kodu, który pokazuje, jak obsługuję CORS w punkcie końcowym 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' }) } }

W powyższym fragmencie kodu powinieneś być w stanie zobaczyć, że zdefiniowałem tablicę allowedOrigins , są to jedyne źródła, które mogą używać tego punktu końcowego. Żądania z dowolnego innego źródła otrzymają kod stanu 403 i komunikat Request blocked by CORS .

Ta funkcja akceptuje również szereg parametrów treści, z których jednym jest amount , którą „klient” zdecydował się zapłacić, jest to wartość z danych wejściowych HTML na stronie MDX Embed. Zauważysz również parametr product , jest to identyfikator produktu zdefiniowany w moim panelu Stripe i sposób, w jaki Stripe API tworzy poprawny adres URL do kasy. Przekazanie tej wartości jako parametru treści zamiast zakodowania jej na sztywno w funkcji pozwala mi ponownie użyć tego punktu końcowego w innych produktach Stripe.

Czy sok wart jest wyciskania?

Wspomniałem po drodze kilka rzeczy, dlaczego zdecydowałem się na tę trasę. W końcu korzystanie z funkcji bezserwerowych może wydawać się bardziej skomplikowanym sposobem, ale mam swoje powody i myślę, że warto. Dlatego.

Paulie API jest zarówno interfejsem API Cross-Origin, jak i witryną z dokumentacją. Oczywiście, jeśli zamierzasz napisać API, musi to być udokumentowane, prawda?

To tutaj działa na moją korzyść, aby użyć Gatsby do zasilania mojego API, ponieważ wraz z funkcjami Serverless API Paulie jest również witryną Gatsby, a ponieważ jest to w rzeczywistości witryna, mogę ją wypełnić treścią i sprawić, by wyglądała ładnie, ale czekaj, jest więcej …

Uwaga: Paulie API to także interaktywny plac zabaw API!

Każda funkcja ma łącze Run in browser . Spowoduje to przejście do strony w witrynie, na której możesz wchodzić w interakcję z funkcją. Służy zarówno jako użyteczny poligon testowy podczas opracowywania funkcji, jak i łatwy sposób na zademonstrowanie, jak działa funkcja, dokumenty są dobre, a interaktywne są lepsze!

Korzystam również z tego interfejsu API, aby zapewnić podobną funkcjonalność po stronie serwera dla moich innych witryn internetowych. Spójrz na stronę Informacje, na której udokumentowałem, które z moich witryn używają jakich funkcji, a oto diagram ilustrujący, jak to wszystko obecnie łączy się w całość.

Schemat funkcji cross origin API Paulie
Możliwości funkcji cross Origin API Paulie. (duży podgląd)

Na powyższym diagramie powinieneś zobaczyć, że https://paulie.dev używa również punktu końcowego Stripe. Użyłem tego samego podejścia, co w przypadku MDX Embed, aby włączyć funkcję „Płać ile chcesz”. To drobiazg, ale ponieważ punkt końcowy make-stripe-payment jest już napisany i działa, mogę go ponownie użyć i uniknąć duplikowania tej funkcjonalności.

Witryna https://paulie.dev ma również własne funkcje bezserwerowe Gatsby, których używam do publikowania reakcji użytkowników na Faunę i przechwytywania zapisów do biuletynów. Ta funkcja jest unikalna dla tej witryny, więc jeszcze jej nie wyodrębniłem. Gdybym jednak chciał zapisać się do newslettera na https://www.pauliescanlon.io, byłby to punkt, w którym przeniosę tę funkcję do Paulie API.

Zrzut ekranu paulie.dev Interfejs użytkownika „Płać ile chcesz”
Paulie.dev w sekcji „Płać ile chcesz”. (duży podgląd)

Abstrakcja

To może wydawać się krokiem wstecz, aby wyabstrahować funkcje bezserwerowe. W końcu jedną z najfajniejszych rzeczy związanych z bezserwerowym rozwiązaniem jest to, że zarówno kod frontowy, jak i kod zaplecza działają w tym samym miejscu. Jak pokazałem, są chwile, w których abstrahowanie ma sens — w każdym razie dla mnie.

Z pewnością czerpię korzyści z zastosowania tego podejścia i planuję dalszy rozwój mojego API, aby zapewnić większą funkcjonalność wielu moim własnym stronom internetowym, ale jeśli interesuje Cię zarabianie na otwartym oprogramowaniu, a Twoja witryna nie jest zbudowana przy użyciu Gatsby , to podejście może być odpowiedzią, której szukałeś.

Chcesz zacząć korzystać z funkcji Gatsby? Zapoznaj się z dokumentacją Gatsby Functions, aby rozpocząć!

Dalsza lektura

Jeśli chcesz dowiedzieć się więcej o funkcjach bezserwerowych, polecam:

  • Książka Swizec Teller „Serverless Handbook For Frontend Engineers”
  • Kurs Benedict's Summer Functions
  • …i oczywiście dokumenty Gatsby

FuncJam

Od 17 sierpnia do 30 września ludzie Gatsby prowadzą konkurs społecznościowy, w którym do wygrania są absolutnie mega nagrody. Jeśli jest jeszcze czas, wpadnij do FuncJam i dołącz do nas. Sprawdź także sekcję Rozmiar w bajtach tego posta na blogu; zawiera pomocne filmy i linki do wielu przykładowych funkcji.

Dziękuję za przeczytanie, a jeśli chcesz omówić coś wspomnianego w tym artykule, zostaw komentarz poniżej lub znajdź mnie na Twitterze.