استثمر البرامج مفتوحة المصدر باستخدام وظائف Gatsby و Stripe
نشرت: 2022-03-10في هذه المقالة ، سأشرح كيف استخدمت وظائف Gatsby و Stripe API لتمكين مساهمات "ادفع ما تريد" التي تساعد في تمويل مشروعي المفتوح المصدر MDX Embed.
ملاحظة : يسمح لك MDX Embed بتضمين محتوى وسائط الطرف الثالث الشائع بسهولة مثل مقاطع فيديو YouTube والتغريدات ومنشورات Instagram ودروس Egghead و Spotify و TikTok وغيرها الكثير مباشرة في .mdx
. - لا يلزم الاستيراد.
وظائف Gatsby Serverless
تفتح وظائف Gatsby عالمًا جديدًا تمامًا لمطوري الواجهة الأمامية لأنها توفر طريقة لكتابة واستخدام التعليمات البرمجية من جانب الخادم دون متاعب صيانة الخادم. تتراوح استخدامات الوظائف الخالية من الخادم من الاشتراكات في الرسائل الإخبارية باستخدام برنامج ConvertKit ، أو إرسال بريد إلكتروني باستخدام SendGrid ، أو حفظ البيانات في قاعدة بيانات مثل Fauna ، أو في هذه الحالة ، قبول المدفوعات الآمنة باستخدام Stripe - القائمة لا تنتهي بصراحة!
تقبل خدمات الجهات الخارجية مثل تلك المذكورة أعلاه الطلبات التي يتم إرسالها من جانب الخادم فقط. هناك عدد من الأسباب لذلك ، ولكن استخدام المفاتيح الآمنة أو الخاصة هو أحد هذه الأسباب عادةً. إن استخدام هذه المفاتيح من جانب الخادم يعني أنها لا تتعرض للعميل (المتصفح) ولا يمكن إساءة استخدامها ، وهنا يمكن أن تساعد وظائف Gatsby's Serverless.
يوفر Gatsby نفس النهج المنطقي للوظائف التي لا تحتاج إلى خادم كما هو الحال مع الصفحات. على سبيل المثال ، توجد صفحات موقع الويب في src/pages
وتوجد وظائف Serverless في src/api
.
بطبيعة الحال ، هناك ما هو أكثر قليلاً من ذلك ، لكن تجربة مطور Gatsby منطقية ومتسقة ، وأنا أحب ذلك تمامًا!
نفس وظائف المنشأ
تسع مرات من أصل عشرة عند العمل مع وظائف بدون خادم ، ستستخدمها بالطريقة التي كان من المفترض أن تُستخدم بها ، على سبيل المثال ، يستخدم موقع الويب الخاص بك وظائفه الخاصة. أسمي هذا الاستخدام نفس وظائف المنشأ أو SOF باختصار. في هذا السيناريو ، يتم نشر كل من الواجهة الأمامية وواجهة برمجة التطبيقات إلى نفس الأصل ، على سبيل المثال www.my-website.com و www.my-website.com/api ، ويكون الاتصال بين الاثنين سلسًا وبالطبع ، اشتعلت فيه النيران بسرعة!
فيما يلي رسم تخطيطي للمساعدة في توضيح كيف يبدو ذلك:
وظائف عبر الأصل
ومع ذلك ، هناك سيناريوهان على الأقل واجهتهما حيث أحتاج إلى ما كنت أسميه "وظائف متعددة المنشأ" (أو COF باختصار). السيناريوهان اللذان أحتاج فيهما إلى COF هما كما يلي:
- أحتاج إلى إمكانات من جانب الخادم ولكن موقع الويب الأصلي لا يمكنه تشغيل وظائف بدون خادم.
- يتم استخدام الوظيفة غير الخاضعة للخادم من قبل أكثر من أصل واحد.
ملحوظة : استخدام Gatsby ليس الطريقة الوحيدة لكتابة وظائف بدون خادم ولكنه أكثر على ذلك في لحظة.
جربت هذا النهج لأول مرة في نوفمبر 2020 قبل إصدار وظائف Gatsby واستخدمت وظائف Netlify لتوفير اتصالات من خادم إلى خادم مع Twitter API ومدونة Gatsby والمحفظة التجارية الخاصة بي. يمكنك أن تقرأ عن هذا النهج هنا: استخدم وظائف Netlify و Twitter API v2 كنظام إدارة محتوى لمدونة Gatsby الخاصة بك.
بعد إصدار وظائف Gatsby في يونيو 2021 ، قمت بإعادة تشكيل ما ورد أعلاه للعمل مع وظائف Gatsby وإليك المزيد من المعلومات حول كيفية القيام بذلك ولماذا: استخدام وظائف Gatsby كواجهة برمجة تطبيقات مجردة.
فيما يلي رسم تخطيطي لتوضيح النهج العام بشكل أفضل.
في الرسم البياني أعلاه ، تم إنشاء website-1.com
باستخدام Gatsby وكان من الممكن أن يستخدم وظائف Serverless (لكن لا) وتم إنشاء website-2.com
باستخدام شيء لا يحتوي على إمكانات وظيفة بدون خادم.
ملاحظة : في كلتا الحالتين ، يحتاج كلاهما إلى استخدام نفس خدمة الجهة الخارجية ، لذا فمن المنطقي تجريد هذه الوظيفة في واجهة برمجة تطبيقات مستقلة.
مثال واجهة برمجة التطبيقات المستقلة ( my-api.com
) هو أيضًا موقع Gatsby ولديه إمكانيات Serverless Function ، ولكن الأهم من ذلك أنه يسمح لمواقع الويب من أصول أخرى باستخدام وظائف Serverless.
أعرف ما تفكر فيه: CORS! حسنًا ، اجلس جيدًا. سأغطي هذا بعد قليل.
تحقيق الدخل من MDX Embed
كان هذا هو الوضع الذي وجدت نفسي فيه مع MDX Embed. تم إنشاء موقع التوثيق لهذا المشروع باستخدام Storybook. لا يحتوي Storybook على إمكانات بدون خادم ، لكنني حقًا كنت بحاجة إلى اتصال من خادم إلى خادم. بلدي الحل؟ لقد أنشأت واجهة برمجة تطبيقات مستقلة تسمى Paulie API.
Paulie API
يمكن لـ Paulie API (مثل مثال API المستقل المذكور أعلاه) قبول الطلبات من مواقع الويب ذات الأصول المختلفة ويمكنه الاتصال بعدد من خدمات الجهات الخارجية المختلفة ، أحدها Stripe.
لتمكين مدفوعات Stripe من MDX Embed ، قمت بإنشاء نقطة نهاية api/make-stripe-payment
على Paulie API والتي يمكنها تمرير المعلومات ذات الصلة من MDX Embed من خلال وظيفة Serverless الخاصة بها وإلى واجهة برمجة تطبيقات Stripe لإنشاء "الخروج". يمكنك رؤية كود src هنا.
بمجرد إنشاء السحب بنجاح ، تقوم Stripe API بإرجاع عنوان URL. يتم تمرير عنوان URL هذا مرة أخرى إلى MDX Embed الذي يفتح نافذة جديدة في المتصفح حيث يمكن "للعملاء" إدخال تفاصيل الدفع الخاصة بهم بأمان على صفحة ويب Stripe ... والازدهار! تدفع لك!
فيما يلي رسم تخطيطي يوضح كيفية عمل ذلك بشكل أفضل:
هذا النهج هو نفسه كما هو مذكور أعلاه حيث يرسل https://mdx-embed.com طلبات إلى https://paulieapi.gatsbyjs.io والتي بدورها تتصل بـ Stripe API باستخدام الاتصال من خادم إلى خادم. ولكن قبل أن نذهب إلى أبعد من ذلك ، يجدر بنا أن نوضح لماذا لم أستخدم react-stripe-js
.
react-stripe-js
react-stripe-js
عبارة عن مجموعة أدوات من جانب العميل (متصفح) تتيح لك إنشاء عمليات سحب شريط وعناصر في مشروع React الخاص بك. باستخدام رد فعل شريطي- js ، يمكنك إعداد طريقة لقبول المدفوعات بأمان دون الحاجة إلى الاتصال من جانب الخادم ، ولكن ... كنت أرغب في تنفيذ مساهمات "ادفع ما تريد". اسمح لي أن أشرح.
إليك لقطة شاشة لـ "منتج" MDX Embed الذي قمت بإعداده في لوحة معلومات Stripe. لاحظ أن السعر هو 1.00 دولار.
إذا استخدمت رد فعل شريطي- js لتمكين المدفوعات ، فسيُطلب من جميع "العملاء" دفع نفس المبلغ. في هذه الحالة ، يبلغ 1.00 دولار فقط وهذا لن يدفع الفواتير!
لتمكين "ادفع ما تريد" (على سبيل المثال ، مبلغ رمزي يختاره "العميل") ، عليك الغوص بشكل أعمق قليلاً واستخدام الاتصال من خادم إلى خادم وإرسال هذا المبلغ إلى Stripe API باستخدام طلب HTTP مخصص. هذا هو المكان الذي أستخدم فيه وظيفة Gatsby وأقوم بتمرير قيمة ديناميكية سيتم استخدامها بعد ذلك لإنشاء تجربة "الخروج" والكتابة فوق السعر المحدد في لوحة معلومات Stripe الخاصة بي.
في MDX Embed ، أضفت HTML <input type="number" />
والذي يسمح "للعملاء" بتعيين مبلغ بدلاً من دفع مبلغ محدد مسبقًا - إذا كانت كل التجارة الإلكترونية فقط على هذا النحو!
إليك مقطع فيديو صغيرًا قمت بإنشائه يوضح كيفية عمل MDX Embed و Paulie API و Stripe API معًا:
من خلال تمرير قيمة الإدخال من MDX Embed إلى Paulie API والتي تتصل بدورها بواجهة برمجة تطبيقات Stripe ، فأنا قادر على إنشاء تسجيل خروج "ديناميكي".
ملاحظة : هذا يعني الآن أن "العملاء" يمكنهم تحديد قيمة المشروع بالنسبة لهم وتحديد مبلغ مناسب للمساهمة.
أود أن أذكر بنديكت راي في هذه المرحلة التي أوضحت لي هذا النهج لأول مرة خلال دورة وظائف الصيف الرائعة. يمكنك معرفة المزيد من خلال زيارة Queen Raae Codes. ( شكرًا بنديكت ، أنت الأفضل! )
لنتحدث عن CORS
افتراضيًا ، لن يتم حظر وظائف Gatsby Serverless بواسطة CORS نظرًا لنشر الواجهة الأمامية وواجهة برمجة التطبيقات إلى نفس الأصل. ومع ذلك ، عند تطوير وظائف Cross-Origin ، ستحتاج إلى تكوين API الخاص بك بحيث يقبل الطلبات من أصول مختلفة عن تلك الخاصة بها.
في ما يلي مقتطف الشفرة لإظهار كيف أتعامل مع CORS في نقطة نهاية 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' }) } }
في مقتطف الشفرة أعلاه ، يجب أن تكون قادرًا على رؤية لقد قمت بتحديد مجموعة من الأصول allowedOrigins
بها ، هذه هي الأصول الوحيدة المسموح بها لاستخدام نقطة النهاية هذه. ستتلقى الطلبات من أي مصدر آخر رمز الحالة 403
ورسالة Request blocked by CORS
.
تقبل هذه الوظيفة أيضًا عددًا من معلمات الجسم ، أحدها هو amount
الذي قرر "العميل" دفعه ، وهي القيمة من إدخال HTML على موقع MDX Embed. ستلاحظ أيضًا معلمة product
، وهذا هو معرف المنتج المحدد في لوحة معلومات Stripe الخاصة بي وكيف تنشئ Stripe API عنوان URL الصحيح "للخروج". يسمح لي تمرير هذه القيمة كمعامل جسم بدلاً من ترميزها في الوظيفة بإعادة استخدام نقطة النهاية هذه لمنتجات Stripe الأخرى.
هل يستحق العصير الضغط؟
لقد ذكرت بعض الأشياء على طول الطريق لماذا قررت السير في هذا الطريق. بعد كل شيء ، قد يبدو الأمر وكأنه طريقة أكثر تعقيدًا لاستخدام وظائف بدون خادم ولكن لدي أسبابي ، وأعتقد أن الأمر يستحق ذلك. إليكم السبب.
Paulie API هي واجهة برمجة تطبيقات مشتركة المنشأ وموقع توثيق. بطبيعة الحال ، إذا كنت ستكتب API ، فيجب توثيقها بشكل صحيح؟
هذا هو المكان الذي يخدم فيه استخدام Gatsby لتشغيل واجهة برمجة التطبيقات (API) الخاصة بي لأنه إلى جانب إمكانات Serverless ، يعد Paulie API أيضًا أحد مواقع Gatsby على الويب ، ولأنه في الواقع موقع ويب يمكنني ملؤه بالمحتوى وجعله يبدو جميلًا ، ولكن انتظر هناك المزيد ...
ملاحظة: Paulie API هو أيضًا ملعب تفاعلي لواجهة برمجة التطبيقات!
كل وظيفة لها ارتباط Run in browser
. ينقلك هذا إلى صفحة على الموقع حيث يمكنك التفاعل مع الوظيفة. إنه بمثابة ساحة اختبار مفيدة أثناء تطوير الوظيفة وطريقة سهلة لتوضيح كيفية عمل الوظيفة ، والمستندات جيدة ، والمستندات التفاعلية أفضل!
أستخدم أيضًا واجهة برمجة التطبيقات هذه لتوفير وظائف مماثلة من جانب الخادم لمواقع الويب الأخرى الخاصة بي. ألق نظرة على صفحة حول حيث قمت بتوثيق أي من المواقع الخاصة بي تستخدم الوظائف ، وإليك رسم تخطيطي لتوضيح كيف يتم تجميعها جميعًا حاليًا.
يجب أن ترى من الرسم التخطيطي أعلاه أن https://paulie.dev يستخدم أيضًا نقطة نهاية Stripe. لقد استخدمت نفس الأسلوب المتبع مع MDX Embed لتمكين وظيفة "ادفع ما تريد". إنه شيء صغير ، ولكن نظرًا لأن نقطة نهاية make-stripe-payment
الشريطي مكتوبة بالفعل وتعمل بالفعل ، يمكنني إعادة استخدامها وتجنب تكرار هذه الوظيفة.
يحتوي موقع https://paulie.dev أيضًا على وظائف Gatsby Serverless الخاصة به والتي أستخدمها لنشر ردود فعل المستخدم على Fauna والتقاط عمليات الاشتراك في الرسائل الإخبارية. هذه الوظيفة فريدة لهذا الموقع ، لذا لم ألخصها بعد. ومع ذلك ، إذا كنت أرغب في الاشتراك في الرسائل الإخبارية على https://www.pauliescanlon.io ، فستكون هذه هي النقطة التي أقوم فيها بترحيل الوظيفة إلى Paulie API.
التجريد
قد يبدو هذا وكأنه خطوة إلى الوراء لاستخلاص وظائف Serverless الخاصة بك. بعد كل شيء ، من أروع الأشياء حول عدم استخدام خادم هو أن كلاً من الكود الأمامي والخلفي يعملان في نفس المكان. كما أوضحت ، هناك أوقات يكون فيها التجريد منطقيًا - بالنسبة لي على أي حال.
أنا بالتأكيد أستفيد من استخدام هذا النهج وأخطط لمواصلة تطوير واجهة برمجة التطبيقات الخاصة بي لتوفير المزيد من الوظائف لعدد من مواقع الويب الخاصة بي ، ولكن إذا كان جني الأموال من المصدر المفتوح يهمك ولم يتم إنشاء موقعك باستخدام Gatsby ، قد يكون هذا النهج هو الإجابة التي كنت تبحث عنها.
هل تريد أن تبدأ مع وظائف Gatsby؟ تحقق من مستندات Gatsby Functions للبدء!
قراءة متعمقة
إذا كنت مهتمًا بمعرفة المزيد حول الوظائف الخالية من الخادم ، فإنني أوصي بما يلي:
- كتاب Swizec Teller ، "Serverless Handbook For Frontend Engineers"
- دورة وظائف بنديكت الصيفية
- ... وبالطبع مستندات غاتسبي
فونكجام
من 17 أغسطس إلى 30 سبتمبر ، يدير أفراد Gatsby مسابقة مجتمعية مع بعض الجوائز الضخمة التي يمكن الفوز بها. إذا كان لا يزال هناك متسع من الوقت ، فانتقل إلى FuncJam وانضم إليه. أيضًا ، تحقق من قسم حجم البايت في منشور المدونة هذا ؛ يحتوي على مقاطع فيديو مفيدة وروابط لعدد من أمثلة الوظائف.
شكرًا على القراءة ، وإذا كنت ترغب في مناقشة أي شيء مذكور في هذه المقالة ، فاترك تعليقًا أدناه أو ابحث عني على Twitter.