Gatsby関数とStripeを使用してオープンソースソフトウェアを収益化する

公開: 2022-03-10
クイックサマリー↬GatsbyFunctionsは、フロントエンド開発者に、サーバーを保守する手間をかけずにサーバー側のコードを記述して使用する方法を提供します。 オープンソースからお金を稼ぐことがあなたにとって興味があり、あなたのサイトがギャツビーを使って構築されていないなら、このアプローチはあなたが探していた答えかもしれません。

この記事では、GatsbyFunctionsとStripeAPIを使用して、オープンソースプロジェクトのMDXEmbedに資金を提供するのに役立つ安全な「希望価格制」の寄付を実現する方法について説明します。

MDX Embedを使用すると、YouTube動画、ツイート、Instagram投稿、Eggheadレッスン、Spotify、TikTokなどの人気のあるサードパーティメディアコンテンツを.mdxに簡単に埋め込むことができます。インポートは必要ありません。

Gatsbyサーバーレス関数

Gatsby Functionsは、サーバーを保守する手間をかけずにサーバー側のコードを記述して使用する方法を提供するため、フロントエンド開発者にまったく新しい世界を開きます。 サーバーレス機能の用途は、ConvertKitを使用したニュースレターの登録、SendGridを使用したメールの送信、Faunaなどのデータベースへのデータの保存、この場合はStripeを使用した安全な支払いの受け入れなど、さまざまです。リストは率直に言って無限です。

上記のようなサードパーティのサービスは、サーバー側に送信されたリクエストのみを受け入れます。 これにはいくつかの理由がありますが、通常、安全なキーまたは秘密のキーを使用することが1つです。 これらのキーをサーバー側で使用するということは、それらがクライアント(ブラウザー)に公開されず、悪用されないことを意味します。ここで、Gatsbyのサーバーレス機能が役立ちます。

Gatsbyは、サーバーレス関数に対して、ページの場合と同じ論理的アプローチを提供します。 たとえば、Webサイトページはsrc/pagesにあり、サーバーレス関数はsrc/apiにあります。

当然、それ以上のものがありますが、Gatsbyの開発者の経験は論理的で一貫性があり、私はそれが大好きです。

同一生成元関数

サーバーレス関数を使用する場合、10回のうち9回は、本来の使用方法で使用します。たとえば、Webサイトは独自の関数を使用します。 私はこの使用法を同一生成元関数または略してSOFと呼びます。 このシナリオでは、フロントエンドとAPIの両方が同じオリジン(www.my-website.com、www.my-website.com / apiなど)にデプロイされ、2つの間の通信はシームレスであり、もちろん、速く燃える!

これは、それがどのように見えるかを説明するのに役立つ図です。

同一生成元関数の図
独自のサーバーレス機能を使用するGatsbyWebサイト。 (大プレビュー)

クロスオリジン関数

ただし、私が「クロスオリジン関数」(または略してCOF)と呼んでいるものが必要になった場合に遭遇したシナリオは少なくとも2つあります。 COFが必要な2つのシナリオは次のとおりです。

  1. サーバー側の機能が必要ですが、元のWebサイトでサーバーレス機能を実行できません。
  2. サーバーレス機能は、複数のオリジンによって使用されます。

サーバーレス関数を作成する方法は、Gatsbyを使用することだけではありませんが、それについてはすぐに詳しく説明します。

Gatsby Functionsがリリースされる前の2020年11月にこのアプローチを最初に試し、Netlify Functionsを使用して、TwitterAPIとGatsbyブログおよび商用ポートフォリオとのサーバー間通信を提供しました。 このアプローチについては、ここで読むことができます。GatsbyブログのCMSとしてNetlify関数とTwitterAPIv2を使用します。

2021年6月にGatsbyFunctionsがリリースされた後、Gatsby Functionsを使用できるように上記をリファクタリングしました。その方法と理由について、もう少し詳しく説明します。抽象化されたAPIとしてGatsbyFunctionsを使用する。

これは、一般的なアプローチをよりよく説明するための図です。

クロスオリジン関数の図
GatsbyAPIのサーバーレス関数を使用する2つのWebサイト。 (大プレビュー)

上の図では、 website-1.comはGatsbyで構築されており、サーバーレス関数を使用できた可能性があります(ただし、使用していません) website-2.comは、サーバーレス関数機能を持たないものを使用して構築されています。

どちらの場合も、どちらも同じサードパーティサービスを使用する必要があるため、この機能をスタンドアロンAPIに抽象化することは理にかなっています。

スタンドアロンAPIの例( my-api.com )もGatsbyサイトであり、サーバーレス機能機能を備えていますが、さらに重要なことに、他のオリジンのWebサイトがサーバーレス機能を使用できるようになっています。

私はあなたが何を考えているか知っています:CORS! まあ、しっかり座ってください。 これについては後ほど説明します。

ジャンプした後もっと! 以下を読み続けてください↓

MDX埋め込みの収益化

これは私がMDX埋め込みで自分自身を見つけた状況でした。 このプロジェクトのドキュメントWebサイトは、Storybookを使用して構築されています。 Storybookにはサーバーレス機能はありませんが、サーバー間の通信が本当に必要でした。 私の解決策? PaulieAPIと呼ばれるスタンドアロンAPIを作成しました。

ポーリーAPI

Paulie API(上記のスタンドアロンAPIの例のように)は、さまざまなオリジンのWebサイトからのリクエストを受け入れ、さまざまなサードパーティサービスに接続できます。そのうちの1つはStripeです。

MDX EmbedからのStripe支払いを有効にするために、PaulieAPIでapi/make-stripe-paymentエンドポイントを作成しました。これにより、MDXEmbedから独自のサーバーレス関数を介してStripeAPIに関連情報を渡して、「チェックアウト」を作成できます。 ここでsrcコードを見ることができます。

チェックアウトが正常に作成されると、StripeAPIはURLを返します。 このURLはMDXEmbedに戻され、ブラウザに新しいウィンドウが開きます。このウィンドウで、「顧客」はStripeWebページに支払いの詳細を安全に入力できます。 あなたは報酬を受け取ります!

これがどのように機能するかをよりよく説明する図を次に示します。

PaulieAPIを使用したMDX埋め込みの図
PaulieAPIのサーバーレス関数を介してStripeAPIに接続するMDXEmbed。 (大プレビュー)

このアプローチは、https://mdx-embed.comがhttps://paulieapi.gatsbyjs.ioにリクエストを送信し、https://paulieapi.gatsbyjs.ioがサーバー間通信を使用してStripeAPIに接続する上記と同じです。 しかし、先に進む前に、 react-stripe-js使用しなかった理由を説明する価値があります。

react-stripe-js

react-stripe-jsは、ReactプロジェクトでStripeチェックアウトと要素を作成できるクライアント側(ブラウザー)のツールキットです。 react-stripe-jsを使用すると、サーバー側の通信を必要とせずに安全に支払いを受け入れる方法を設定できますが、…そしてそれはあります。 「望む額を支払う」貢献を実装したかったのです。 説明させてください。

これは、Stripeダッシュボードに設定したMDX埋め込み「製品」のスクリーンショットです。 価格が$1.00であることに注意してください。

MDX埋め込み製品の価格が$1.00のStripeダッシュボードのスクリーンショット
ストライプダッシュボード製品セクション。 (大プレビュー)

私がreact-stripe-jsを使用して支払いを有効にした場合、すべての「顧客」は同じ金額を支払うように求められます。 この場合、たったの$ 1.00で、請求書を支払う必要はありません。

「希望価格を支払う」(たとえば、「顧客」が選択したわずかな金額)を有効にするには、もう少し深く掘り下げてサーバー間通信を使用し、カスタムHTTPリクエストを使用してこの金額をStripeAPIに送信する必要があります。 ここでGatsby関数を使用し、動的な値を渡します。この値を使用して、「チェックアウト」エクスペリエンスを作成し、Stripeダッシュボードで定義された価格を上書きします。

MDX Embedに、HTML <input type="number" />を追加しました。これにより、「顧客」は事前定義された金額を支払うのではなく、金額を設定できます。

これは、MDX Embed、Paulie API、およびStripeAPIがすべてどのように連携するかを示す私が作成した小さなビデオです。

MDX Embed、Paulie API、およびStripe APIがどのように連携して、「希望価格制」を実現するか。

MDXEmbedからの入力値をPaulieAPIに渡し、Paulie APIがStripeAPIに接続することで、「動的」チェックアウトを作成できます。

これは、「顧客」がプロジェクトの価値を決定し、貢献する適切な金額を設定できることを意味します。

この時点で、彼女の素晴らしいサマーファンクションコースでこのアプローチを最初に見せてくれたベネディクトラーエに言及したいと思います。 詳細については、QueenRaaeCodesをご覧ください。 (ベネディクトに感謝​​します、あなたは最高です!

CORSについて話しましょう

デフォルトでは、フロントエンドとAPIが同じオリジンにデプロイされているため、Gatsbyサーバーレス関数はCORSによってブロックされません。 ただし、クロスオリジン関数を開発する場合は、APIを構成して、独自のオリジンとは異なるオリジンからのリクエストを受け入れるようにする必要があります。

api/make-stripe-paymentエンドポイントでCORSを処理する方法を示すコードスニペットを次に示します。

 // 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の配列を定義したことがわかります。これらは、このエンドポイントの使用が許可されている唯一のオリジンです。 他の発信元からのリクエストは、ステータスコード403Request blocked by CORSのメッセージを受け取ります。

この関数は、多くのボディパラメータも受け入れます。そのうちの1つは、「顧客」が支払うことを決定したamountです。これは、MDX埋め込みサイトのHTML入力からの値です。 また、 productパラメーターに気付くでしょう。これは、私のStripeダッシュボードで定義された製品IDであり、StripeAPIが正しい「チェックアウト」URLを作成する方法です。 この値を関数にハードコーディングするのではなく、bodyパラメーターとして渡すことで、このエンドポイントを他のStripe製品で再利用できます。

ジュースは絞る価値がありますか?

このルートに行くことにした理由について、途中でいくつか言及しました。 結局のところ、サーバーレス関数を使用するのはもっと複雑な方法のように思えるかもしれませんが、私には理由があり、それだけの価値があると思います。 これが理由です。

Paulie APIは、クロスオリジンAPIであると同時にドキュメントサイトでもあります。 当然、APIを作成する場合は、正しく文書化する必要がありますか?

ここで、Gatsbyを使用してAPIを強化することができます。これは、サーバーレス機能とともにPaulieAPIもGatsbyWebサイトであり、実際にはWebサイトであるため、コンテンツで埋めて見栄えを良くすることができるためです。 …

注: Paulie APIは、インタラクティブなAPIプレイグラウンドでもあります。

各関数には、 Run in browserリンクがあります。 これにより、関数を操作できるサイトのページに移動します。 これは、関数を開発しているときの便利なテストの場としても、関数がどのように機能するかを示す簡単な方法としても役立ちます。ドキュメントは優れており、インタラクティブなドキュメントの方が優れています。

また、このAPIを使用して、他のWebサイトに同様のサーバー側機能を提供しています。 どのサイトがどの機能を使用しているかを文書化したAboutページを見てください。これは、現在すべてがどのように組み合わされているかを示す図です。

PaulieAPIのクロスオリジン関数の図
PaulieAPIクロスオリジン関数機能。 (大プレビュー)

上の図から、https://paulie.devもStripeエンドポイントを使用していることがわかります。 MDX Embedと同じアプローチを使用して、「希望価格制」機能を有効にしました。 小さなことですが、 make-stripe-paymentエンドポイントはすでに作成されて機能しているので、再利用してこの機能の重複を避けることができます。

https://paulie.dev Webサイトには、独自のGatsbyサーバーレス関数もあります。これを使用して、動物相に対するユーザーの反応を投稿したり、ニュースレターの登録を取得したりします。 この機能はこのサイトに固有のものであるため、まだ抽象化していません。 ただし、https://www.pauliescanlon.ioでニュースレターの登録が必要な場合は、これが関数をPaulieAPIに移行するポイントになります。

paulie.devのスクリーンショット「望む額を支払う」ユーザーインターフェイス
paulie.devの「望む額を支払う」セクション。 (大プレビュー)

抽象化

これは、サーバーレス関数を抽象化するための一歩後退のように見えるかもしれません。 結局のところ、サーバーレス化の最も優れた点の1つは、フロントエンドコードとバックエンドコードの両方が同じ場所にあることです。 私が示したように、抽象化が理にかなっている場合があります—とにかく私には。

私は確かにこのアプローチを使用することで恩恵を受けており、APIをさらに開発して、自分の多くのWebサイトにより多くの機能を提供する予定ですが、オープンソースからお金を稼ぐことに関心があり、サイトがGatsbyを使用して構築されていない場合、このアプローチはあなたが探していた答えかもしれません。

Gatsby Functionsを使い始めたいですか? Gatsby Functionsのドキュメントをチェックして、始めましょう!

参考文献

サーバーレス機能について詳しく知りたい場合は、次のことをお勧めします。

  • Swizec Tellerの本、「フロントエンドエンジニアのためのサーバーレスハンドブック」
  • ベネディクトのサマーファンクションコース
  • …そしてもちろん、Gatsbyのドキュメント

FuncJam

8月17日から9月30日まで、ギャツビーの人々はコミュニティコンテストを開催し、いくつかの絶対にメガプライズを獲得します。 まだ時間があれば、FuncJamにアクセスして参加してください。また、このブログ投稿のバイトサイズのセクションも確認してください。 役立つビデオといくつかの関数例へのリンクが含まれています。

読んでくれてありがとう。この記事で言及されていることについて話し合いたい場合は、下にコメントを残すか、Twitterで私を見つけてください。