Uangkan Perangkat Lunak Sumber Terbuka Dengan Fungsi dan Garis Gatsby
Diterbitkan: 2022-03-10Dalam artikel ini, saya akan menjelaskan bagaimana saya menggunakan Gatsby Functions dan Stripe API untuk mengaktifkan kontribusi "Bayar apa yang Anda inginkan" yang membantu mendanai proyek open-source saya, MDX Embed.
Catatan : MDX Embed memungkinkan Anda untuk dengan mudah menyematkan konten media pihak ketiga yang populer seperti video YouTube, Tweet, postingan Instagram, pelajaran Egghead, Spotify, TikTok, dan banyak lagi langsung ke .mdx
Anda — tidak perlu mengimpor.
Fungsi Tanpa Server Gatsby
Fungsi Gatsby membuka dunia baru bagi pengembang front-end karena mereka menyediakan cara untuk menulis dan menggunakan kode sisi server tanpa kerumitan memelihara server. Penggunaan untuk Fungsi Tanpa Server berkisar dari pendaftaran Newsletter dengan ConvertKit, mengirim email menggunakan SendGrid, menyimpan data dalam database seperti Fauna, atau dalam hal ini, menerima pembayaran aman menggunakan Stripe — daftarnya sejujurnya tidak ada habisnya!
Layanan pihak ketiga seperti yang disebutkan di atas hanya akan menerima permintaan yang dikirim dari sisi server. Ada beberapa alasan untuk ini, tetapi menggunakan kunci aman atau pribadi biasanya salah satunya. Menggunakan kunci ini di sisi server berarti mereka tidak terpapar ke klien (browser) dan tidak dapat disalahgunakan, dan di sinilah Fungsi Tanpa Server Gatsby dapat membantu.
Gatsby menyediakan pendekatan logis yang sama untuk Fungsi Tanpa Server seperti yang mereka lakukan dengan halaman. Misalnya, halaman situs web terletak di src/pages
dan Fungsi Tanpa Server terletak di src/api
.
Tentu, ada sedikit lebih dari itu tetapi pengalaman pengembang Gatsby logis dan konsisten, dan saya sangat menyukainya!
Fungsi Asal yang Sama
Sembilan dari sepuluh saat bekerja dengan Fungsi Tanpa Server, Anda akan menggunakannya sebagaimana mestinya, Misalnya, situs web Anda menggunakan fungsinya sendiri. Saya menyebut penggunaan ini Same Origin Functions atau disingkat SOF. Dalam skenario ini, Front-end dan API disebarkan ke asal yang sama, Misalnya www.my-website.com, dan www.my-website.com/api, dan komunikasi antara keduanya lancar dan, tentu saja , sangat cepat!
Berikut adalah diagram untuk membantu menggambarkan seperti apa:
Fungsi Lintas Asal
Namun, setidaknya ada dua skenario yang saya temui di mana saya membutuhkan apa yang saya sebut "Fungsi Lintas-Asal" (atau disingkat COF). Dua skenario di mana saya membutuhkan COF adalah sebagai berikut:
- Saya membutuhkan kemampuan sisi server tetapi situs web asal tidak dapat menjalankan Fungsi Tanpa Server.
- Fungsi Tanpa Server digunakan oleh lebih dari satu asal.
Catatan : Menggunakan Gatsby bukan satu-satunya cara untuk menulis Fungsi Tanpa Server tetapi lebih dari itu sebentar lagi.
Saya pertama kali bereksperimen dengan pendekatan ini pada November 2020 sebelum rilis Fungsi Gatsby dan menggunakan Fungsi Netlify untuk menyediakan komunikasi server-ke-server dengan API Twitter dan blog Gatsby saya serta portofolio komersial. Anda dapat membaca tentang pendekatan ini di sini: Gunakan Netlify Functions dan Twitter API v2 sebagai CMS untuk blog Gatsby Anda.
Setelah rilis Fungsi Gatsby pada Juni 2021, saya memfaktorkan ulang hal di atas agar berfungsi dengan Fungsi Gatsby dan inilah sedikit informasi lebih lanjut tentang bagaimana saya melakukannya dan alasannya: Menggunakan Fungsi Gatsby sebagai API yang diabstraksi.
Berikut adalah diagram untuk lebih menggambarkan pendekatan umum.
Dalam diagram di atas, website-1.com
dibangun dengan Gatsby dan dapat menggunakan Fungsi Tanpa Server (tetapi tidak) dan website-2.com
dibuat menggunakan sesuatu yang tidak memiliki kemampuan Fungsi Tanpa Server.
Catatan : Dalam kedua kasus, keduanya perlu menggunakan layanan pihak ketiga yang sama sehingga masuk akal untuk mengabstraksi fungsi ini menjadi API mandiri.
Contoh API mandiri ( my-api.com
) juga merupakan situs Gatsby dan memiliki kemampuan Fungsi Tanpa Server, tetapi yang lebih penting, ini memungkinkan situs web dari asal lain untuk menggunakan Fungsi Tanpa Servernya.
Saya tahu apa yang Anda pikirkan: CORS! Nah, duduklah. Saya akan membahas ini segera.
Memonetisasi Embed MDX
Ini adalah situasi yang saya alami dengan MDX Embed. Website dokumentasi untuk proyek ini dibangun menggunakan Storybook. Storybook tidak memiliki kemampuan tanpa server tetapi saya benar-benar membutuhkan komunikasi server-ke-server. solusi saya? Saya membuat API mandiri bernama Paulie API.
API Paulie
Paulie API (seperti contoh API mandiri yang disebutkan di atas) dapat menerima permintaan dari situs web asal yang berbeda dan dapat terhubung ke sejumlah layanan pihak ketiga yang berbeda, salah satunya adalah Stripe.
Untuk mengaktifkan pembayaran Stripe dari MDX Embed, saya membuat titik akhir api/make-stripe-payment
di Paulie API yang dapat meneruskan informasi yang relevan dari MDX Embed melalui Fungsi Tanpa Servernya sendiri dan ke Stripe API untuk membuat "checkout". Anda dapat melihat kode src di sini.
Setelah checkout berhasil dibuat, Stripe API mengembalikan URL. URL ini diteruskan kembali ke MDX Embed yang membuka jendela baru di browser di mana "pelanggan" dapat dengan aman memasukkan detail pembayaran mereka di halaman web Stripe… dan boom! Anda dibayar!
Berikut adalah diagram yang lebih baik menggambarkan cara kerjanya:
Pendekatan ini sama seperti yang disebutkan di atas di mana https://mdx-embed.com mengirimkan permintaan ke https://paulieapi.gatsbyjs.io yang pada gilirannya terhubung ke Stripe API menggunakan komunikasi server-ke-server. Tetapi sebelum kita melangkah lebih jauh, ada baiknya menjelaskan mengapa saya tidak menggunakan react-stripe-js
.
react-stripe-js
react-stripe-js
adalah toolkit (browser) sisi klien yang memungkinkan Anda membuat checkout Stripe dan elemen dalam proyek React Anda. Dengan react-stripe-js Anda dapat mengatur metode untuk menerima pembayaran dengan aman tanpa perlu komunikasi sisi server, tapi… Saya ingin menerapkan kontribusi "Bayar apa yang Anda inginkan". Izinkan saya untuk menjelaskan.
Berikut adalah tangkapan layar "produk" Embed MDX yang telah saya siapkan di dasbor Stripe saya. Perhatikan harganya $1,00.
Jika saya menggunakan react-stripe-js untuk mengaktifkan pembayaran, semua "pelanggan" akan diminta untuk membayar jumlah yang sama. Dalam hal ini, hanya $1,00 dan itu tidak akan membayar tagihan kan!
Untuk mengaktifkan "Bayar apa yang Anda inginkan" (misalnya jumlah nominal yang dipilih oleh "pelanggan"), Anda harus menyelam lebih dalam dan menggunakan komunikasi server-ke-server dan mengirimkan jumlah ini ke Stripe API menggunakan permintaan HTTP khusus. Di sinilah saya menggunakan Fungsi Gatsby dan saya memberikan nilai dinamis yang kemudian akan digunakan untuk menciptakan pengalaman "checkout" dan menimpa harga yang ditentukan di dasbor Stripe saya.
Di MDX Embed, saya telah menambahkan <input type="number" />
HTML yang memungkinkan "pelanggan" untuk menetapkan jumlah daripada membayar jumlah yang telah ditentukan — jika saja semua e-niaga seperti ini!
Berikut adalah video kecil yang saya buat yang menunjukkan bagaimana MDX Embed, Paulie API, dan Stripe API bekerja bersama:
Dengan meneruskan nilai input dari MDX Embed ke Paulie API yang pada gilirannya terhubung ke Stripe API, saya dapat membuat checkout "dinamis".
Catatan : Sekarang ini berarti bahwa “pelanggan” dapat memutuskan nilai proyek bagi mereka dan menetapkan jumlah yang sesuai untuk disumbangkan.
Saya ingin menyebutkan Benedicte Raae pada titik ini yang pertama kali menunjukkan kepada saya pendekatan ini selama kursus Fungsi Musim Panasnya yang luar biasa. Anda dapat mengetahui lebih lanjut dengan mengunjungi Queen Raae Codes. ( Terima kasih Benedicte, kamu yang terbaik! )
Mari Bicara Tentang CORS
Secara default, Fungsi Tanpa Server Gatsby tidak akan diblokir oleh CORS karena Front-end dan API di-deploy ke asal yang sama. Namun, saat mengembangkan Fungsi Cross-Origin, Anda harus mengonfigurasi API Anda sehingga menerima permintaan dari asal yang berbeda dengan asalnya sendiri.
Berikut cuplikan kode untuk menunjukkan bagaimana saya menangani CORS di titik akhir 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' }) } }
Dalam cuplikan kode di atas, Anda seharusnya dapat melihat bahwa saya telah mendefinisikan sebuah array dari allowedOrigins
, ini adalah satu-satunya asal yang diizinkan untuk menggunakan titik akhir ini. Permintaan dari asal lain akan menerima kode status 403
dan pesan Request blocked by CORS
.
Fungsi ini juga menerima sejumlah parameter tubuh, salah satunya adalah amount
yang "pelanggan" putuskan untuk bayar, ini adalah nilai dari input HTML di situs Embed MDX. Anda juga akan melihat parameter product
, ini adalah id produk yang ditentukan di dasbor Stripe saya dan bagaimana API Stripe membuat URL "pembayaran" yang benar. Melewati nilai ini sebagai parameter tubuh daripada mengkodekannya dalam fungsi memungkinkan saya untuk menggunakan kembali titik akhir ini untuk produk Stripe lainnya.
Apakah Jus Layak Diperas?
Saya telah menyebutkan beberapa hal di sepanjang jalan mengapa saya memutuskan untuk mengambil rute ini. Bagaimanapun, ini mungkin tampak seperti cara yang lebih rumit untuk menggunakan Fungsi Tanpa Server tetapi saya punya alasan, dan saya pikir itu sepadan. Inilah alasannya.
Paulie API adalah Cross-Origin API dan situs dokumentasi. Tentu saja, jika Anda akan menulis API, itu harus didokumentasikan bukan?
Di sinilah menguntungkan saya untuk menggunakan Gatsby untuk memberi daya pada API saya karena bersama dengan kemampuan Tanpa Server, Paulie API juga merupakan situs web Gatsby, dan karena itu sebenarnya adalah situs web, saya dapat mengisinya dengan konten dan membuatnya terlihat cantik, tapi tunggu masih ada lagi …
Catatan: Paulie API juga merupakan taman bermain API interaktif!
Setiap fungsi memiliki tautan Run in browser
. Ini membawa Anda ke halaman di situs tempat Anda dapat berinteraksi dengan fungsi tersebut. Ini berfungsi sebagai tempat pengujian yang berguna saat saya mengembangkan fungsi dan cara mudah untuk menunjukkan cara kerja fungsi, dokumen bagus, dokumen interaktif lebih baik!
Saya juga menggunakan API ini untuk menyediakan fungsionalitas sisi server yang serupa untuk situs web saya yang lain. Lihatlah halaman Tentang di mana saya telah mendokumentasikan situs saya yang menggunakan fungsi mana, dan berikut adalah diagram untuk menggambarkan bagaimana semuanya saat ini bersatu.
Anda akan melihat dari diagram di atas bahwa https://paulie.dev juga menggunakan titik akhir Stripe. Saya telah menggunakan pendekatan yang sama seperti dengan MDX Embed untuk mengaktifkan fungsionalitas "Bayar apa yang Anda inginkan". Ini hal kecil, tetapi karena titik akhir make-stripe-payment
sudah ditulis dan berfungsi, saya dapat menggunakannya kembali dan menghindari duplikasi fungsi ini.
Situs web https://paulie.dev juga memiliki Fungsi Tanpa Server Gatsby sendiri yang saya gunakan untuk memposting reaksi pengguna terhadap Fauna dan menangkap pendaftaran Newsletter. Fungsionalitas ini unik untuk situs ini, jadi saya belum mengabstraksikannya. Namun, jika saya ingin mendaftar buletin di https://www.pauliescanlon.io, ini akan menjadi titik di mana saya memigrasikan fungsi ke Paulie API.
Abstraksi
Ini mungkin tampak seperti langkah mundur untuk mengabstraksi Fungsi Tanpa Server Anda. Lagi pula, salah satu hal paling keren tentang tanpa server adalah bahwa kode front-end dan back-end Anda berada di tempat yang sama. Seperti yang telah saya tunjukkan, ada saat-saat di mana abstraksi masuk akal — bagi saya bagaimanapun juga.
Saya tentu mendapat manfaat dari menggunakan pendekatan ini dan berencana untuk lebih mengembangkan API saya untuk menyediakan lebih banyak fungsionalitas ke sejumlah situs web saya sendiri, tetapi jika menghasilkan uang dari sumber terbuka menarik bagi Anda dan situs Anda tidak dibangun menggunakan Gatsby , pendekatan ini mungkin merupakan jawaban yang Anda cari.
Ingin memulai dengan Fungsi Gatsby? Lihat dokumen Gatsby Functions untuk memulai!
Bacaan lebih lanjut
Jika Anda tertarik untuk mempelajari lebih lanjut tentang Fungsi Tanpa Server, saya akan merekomendasikan:
- Buku Swizec Teller, “Buku Pegangan Tanpa Server Untuk Insinyur Frontend”
- Kursus Acara Musim Panas Benedict
- …dan, tentu saja, dokumen Gatsby
FuncJam
Dari 17 Agustus hingga 30 September, orang-orang Gatsby mengadakan kompetisi komunitas dengan beberapa hadiah yang sangat besar untuk dimenangkan. Jika masih ada waktu, kunjungi FuncJam dan bergabunglah. Juga, lihat bagian ukuran Byte dari posting blog ini; itu berisi video yang bermanfaat dan tautan ke sejumlah fungsi contoh.
Terima kasih telah membaca, dan jika Anda ingin mendiskusikan apa pun yang disebutkan dalam artikel ini, tinggalkan komentar di bawah atau temukan saya di Twitter.