Gatsby関数を使用したAPIの構築
公開: 2022-03-10サーバーレス関数について聞いたことがあるかもしれませんが、聞いたことがない場合は、サーバーレス関数は、サーバー側のインフラストラクチャにとらわれることなくフロントエンドコードと一緒に実装できる、サーバー側のテクノロジに通常関連付けられている機能を提供します。
サーバー側とクライアント側のコードが同じコードベースに共存しているため、私のようなフロントエンド開発者は、すでに知っていて気に入っているツールを使用して、可能なことの範囲を広げることができます。
制限事項
共存は素晴らしいですが、サーバーレス関数をこのように使用することが目前のタスクに完全に適合しなかった場合に遭遇したシナリオが少なくとも2つあります。 それらは次のとおりです。
- フロントエンドはサーバーレス機能をサポートできませんでした。
- 同じ機能が複数のフロントエンドで必要でした。
コンテキストを提供するために、上記のポイント1と2の両方の1つの例を示します。 私はMDXEmbedと呼ばれるオープンソースプロジェクトを維持しています。ドキュメントサイトから、GatsbyWebサイトではないことがわかります。 Storybookを使用して構築されており、Storybook自体はサーバーレス機能機能を提供しません。 このプロジェクトに資金を提供するために「望む額を支払う」寄付を実装したかったのですが、Stripeを使用して安全な支払いを可能にしたかったのですが、安全な「バックエンド」がなければこれは不可能でした。
この機能をGatsbyFunctionsで構築されたAPIに抽象化することで、MDX Embedで必要な機能を実現し、同じ機能を再利用して、ブログで「希望価格制」機能を有効にすることができました。
私がそれをどのように行ったかについて詳しくは、Gatsby関数とStripeを使用してオープンソースソフトウェアを収益化するをご覧ください。
この時点で、Gatsby関数の使用はフロントエンドまたはBFFの一種のバックエンドとして機能でき、この方法での開発はAPI(アプリケーションプログラミングインターフェイス)の開発に似ています。
APIは、ログイン、リアルタイムのデータフェッチ、ブラウザだけでは適切に処理されない安全なタスクなどを処理するためにフロントエンドコードによって使用されます。 このチュートリアルでは、Gatsby Functionsを使用してAPIを構築し、それをGatsbyCloudにデプロイする方法について説明します。
飛行前チェック
Gatsby関数はGatsbyCloudまたはNetlifyにデプロイすると機能します。このチュートリアルでは、Gatsby Cloudにデプロイする方法を説明するため、最初にサインアップして無料のアカウントを作成する必要があります。
また、GitHub、GitLab、またはBitBucketアカウントのいずれかが必要になります。これは、Gatsby Cloudがコードを読み取り、「サイト」(この場合はAPI)を構築する方法です。
このチュートリアルでは、GitHubを使用します。 先に進みたい場合は、完成したデモAPIコードを私のGitHubで見つけることができます。
入門
ローカルドライブのどこかに新しいディレクトリを作成し、ターミナルで次のコマンドを実行します。 これにより、デフォルトのpackage.json
が設定されます。
npm init -y
依存関係
ターミナルに次のように入力して、必要な依存関係をインストールします。
npm install gatsby react react-dom
ページ
APIに「ページ」がない可能性がありますが、ブラウザでルートURLにアクセスしたときにGatsbyのデフォルトのページ欠落警告が表示されないようにするには、 src/pages/index.js
とsrc/pages/404.js
。
//src/pages/index.js & src/pages/404.js export default () => null;
API
以下をsrc/api/my-first-function.js
に追加します。
'Access-Control-Allow-Origin', '*'
意味については少し後で説明しますが、要するに、他のオリジンからのAPIがCORSによってブロックされないようにします。
//src/api/my-first-function.js export default function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); res.status(200).json({ message: 'A ok!' }); }
スクリプト
package.json
に以下を追加します。
//package.json ... "scripts": { "develop": "gatsby develop", "build": "gatsby build" }, ...
GatsbyDevelopmentServerを起動します
Gatsby開発サーバーを起動するには、ターミナルで次のコマンドを実行します。
npm run develop
ブラウザからリクエストする
Gatsbyの開発サーバーが実行されている状態で、http:// localhost:8000 / api / my-first-functionにアクセスできます。これは単純なGET
リクエストであるため、ブラウザーに次のように表示されます。
{ "message": "A ok!" }
おめでとう
Gatsby関数を使用してAPIを開発しました。
配備
ブラウザに上記の応答が表示されている場合は、関数がローカルで正しく機能していると見なすのが安全です。次の手順では、APIをGatsby Cloudにデプロイし、CodeSandboxからのHTTP
リクエストを使用してアクセスする方法を説明します。
コードをGitにプッシュする
Gatsby Cloudにデプロイする前に、選択したGitプロバイダーにコードをプッシュする必要があります。
ギャツビークラウド
Gatsby Cloudアカウントにログインし、「サイトの追加+」という大きな紫色のボタンを探します。
次のステップでは、Gitリポジトリからインポートするか、テンプレートから開始するかを尋ねられます。GitリポジトリImport from Git Repository
選択して、[ next
へ]をクリックします。
上記のように、Gatsby CloudはGitHub、GitLab、またはBitbucketのいずれかに接続できます。 好みのGitプロバイダーを選択し、[ next
へ]をクリックします。
Gitプロバイダーを接続すると、リポジトリを検索して、サイトに名前を付けることができます。
リポジトリを選択し、サイトに名前を付けたら、[ next
へ]をクリックします。
「統合」と「セットアップ」は必要ないため、スキップできます。
すべての計画が完了した場合は、以下のスクリーンショットのようなものが表示されるはずです。
画面の左側の上部近くにgatsbyjs.io
で終わるURLが表示されます。これはAPIのURLになり、作成した関数には/api/name-of-function
を追加してアクセスできます。このURLの最後まで/api/name-of-function
します。
たとえば、デモAPI用にデプロイされたmy-first-function.js
の完全なバージョンは次のとおりです。
デモAPI:私の最初の関数。
APIのテスト
APIのURLにアクセスすることは1つのことですが、実際にはAPIが通常どのように使用されるかではありません。 理想的には、APIをテストするには、完全に無関係なオリジンから関数にリクエストを送信する必要があります。
ここにres.setHeader('Access-Control-Allow-Origin', '*');
救助に来る。 ドメイン(Webサイト)が関数にアクセスできるようにすることは必ずしも望ましいことではありませんが、ほとんどの場合、パブリック関数はそれだけでパブリックです。 アクセス制御ヘッダーを値*
に設定すると、すべてのドメインが関数にアクセスできます。これがないと、APIがホストされているドメイン以外のドメインがCORSによってブロックされます。
これは、デモAPI my-first-function
を使用するCodeSandboxです。 これをフォークし、AxiosリクエストURLを変更して関数をテストできます。
CodeSandbox:私の最初の関数
ファンシーになる
message: "A ok!"
を示す応答をAPIから送信します。 必ずしもエキサイティングではないので、次のビットでは、GitHub REST APIにクエリを実行し、作成したAPIを使用して自分のサイトに表示する個人プロファイルカードを作成する方法を示します。これは少し次のようになります。 。
CodeSandbox:デモプロファイルカード
依存関係
GitHub REST APIを使用するには、@ octokit/restパッケージをインストールする必要があります。
npm install @octokit/rest
GitHubユーザーを生で取得
以下をsrc/api/get-github-user-raw.js
します。
// src/api/get-github-user-raw.js import { Octokit } from '@octokit/rest'; const octokit = new Octokit({ auth: process.env.OCTOKIT_PERSONAL_ACCESS_TOKEN }); export default async function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); try { const { data } = await octokit.request(`GET /users/{username}`, { username: 'PaulieScanlon' }); res.status(200).json({ message: 'A ok!', user: data }); } catch (error) { res.status(500).json({ message: 'Error!' }); } }
アクセストークン
GitHub REST APIと通信するには、アクセストークンが必要です。 これは、GitHub:パーソナルアクセストークンの作成からこのガイドの手順に従うことで取得できます。
.env
変数
アクセストークンを安全に保つには、以下を.env.development
と.env.production
に追加します。
OCTOKIT_PERSONAL_ACCESS_TOKEN=123YourAccessTokenABC
Gatsby環境変数の詳細については、このガイドのGatsby:EnvironmentVariablesを参照してください。
開発サーバーを起動します
以前と同じように、ターミナルに次のように入力してGatsby開発サーバーを起動します。
npm run develop
ブラウザからリクエストする
Gatsby開発サーバーが実行されている状態で、http:// localhost:8000 / api / get-github-user-rawにアクセスできます。これも単純なGET
リクエストであるため、ブラウザーに次のように表示されます。 (簡潔にするために、応答の一部を削除しました。 )
{ "message": "A ok!", "user": { "login": "PaulieScanlon", "id": 1465706, "node_id": "MDQ6VXNlcjE0NjU3MDY=", "avatar_url": "https://avatars.githubusercontent.com/u/1465706?v=4", "gravatar_id": "", "url": "https://api.github.com/users/PaulieScanlon", "type": "User", "site_admin": false, "name": "Paul Scanlon", "company": "Paulie Scanlon Ltd.", "blog": "https://www.paulie.dev", "location": "Worthing", "email": "[email protected]", "hireable": true, "bio": "Jamstack Developer / Technical Content Writer (freelance)", "twitter_username": "pauliescanlon", "created_at": "2012-02-23T13:43:26Z", "two_factor_authentication": true, ... } }
これは、完全な生の応答のCodeSandboxの例です。
CodeSandbox:生の応答
上記から、実際には必要のない大量のデータが返されることがわかります。この次のビットはAPIであるため完全にあなた次第ですが、GitHubAPIの応答を少し操作すると便利です。フロントエンドコードに送り返す前に。
同じことをしたい場合は、新しい関数を作成して、以下をsrc/api/get-github-user.js
追加できます。
// src/api/get-github-user.js import { Octokit } from '@octokit/rest'; const octokit = new Octokit({ auth: process.env.OCTOKIT_PERSONAL_ACCESS_TOKEN }); export default async function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); try { const { data } = await octokit.request(`GET /users/{username}`, { username: 'PaulieScanlon' }); res.status(200).json({ message: 'A ok!', user: { name: data.name, blog_url: data.blog, bio: data.bio, photo: data.avatar_url, githubUsername: `@${data.login}`, githubUrl: data.html_url, twitterUsername: `@${data.twitter_username}`, twitterUrl: `https://twitter.com/${data.twitter_username}` } }); } catch (error) { res.status(500).json({ message: 'Error!' }); } }
上記からわかるように、GitHub REST APIによって返される完全なデータオブジェクトを返すのではなく、必要なビットだけを選び、名前を変更して、ユーザー名とURLの値の前に数ビットを追加します。 これにより、フロントエンドコードでデータをレンダリングするときに、作業が少し楽になります。
これは、フォーマットされた応答のCodeSandboxの例です。
CodeSandbox:フォーマットされた応答
これは以前のプロファイルカードCodeSandboxと非常に似ていますが、操作された各データ項目がどのように使用されているかを確認できるように、データも印刷しました。
この時点で、このチュートリアルの4つのCodeSandboxデモはすべてデモAPIを使用しており、Gatsbyを使用して構築されたり、GatsbyCloudでホストされたりすることはありません。
.env
変数
2つの新しい関数をデプロイする前に、GitHubAccessトークンをGatsbyCloudの環境変数セクションに追加する必要があります。
ここからどこへ行くの?
私は自分自身にこの質問をしました。 通常、サーバーレス関数はクライアント側のリクエストで使用されますが、それでも問題ありませんが、ユーザーのJavaScriptで無効になっている場合とされていない場合があるJavaScriptに依存するのではなく、ビルド時にデータを静的にページに「ベイク」するために使用できるかどうか疑問に思いました。ブラウザ。
…それがまさに私がしたことです。
これは、実行時とビルド時の両方でGatsbyFunctionsから返されたデータを使用する一種のデータダッシュボードです。 Astroを使用してこのサイトを構築し、GitHubPagesをデプロイしました。
これが優れたアプローチだと思う理由は、何も複製せずにサーバーとブラウザーの両方で同じ機能を再利用できるためです。
このAstroビルドでは、APIによって公開された同じエンドポイントをヒットしてデータを返し、ページにベイクされるか(SEOに最適)、実行時にブラウザーによってフェッチされます(最新または最新のライブデータを表示するのに最適) 。
データダッシュボード
サイトの左側に表示されるデータは、ビルド時にリクエストされ、Astroでページにベイクされます。 ページの右側のデータは、実行時にクライアント側のリクエストを使用してリクエストされます。 GitHub REST APIによって公開されるわずかに異なるエンドポイントを使用して、さまざまなリストを作成するさまざまなGitHubユーザーアカウントにクエリを実行しました。
このサイトに表示されるものはすべて、私のより完全なAPIによって提供されます。 私はそれをポーリーAPIと呼んでおり、多くのWebサイトで使用しています。
ポーリーAPI
このチュートリアルのAPIのようなPaulieAPIはGatsbyで構築されていますが、GatsbyはサイトとAPIの両方として機能できるため、すべての機能がどのように機能するかを文書化するために使用しました。各エンドポイントには、インタラクティブとして使用できる独自のページがあります。遊び場…お気軽にご覧ください。
これで、任意の技術スタックで構築された任意のWebサイトから、任意のクライアント側またはサーバー側のコードで使用できるGatsbyFunctionsAPIができました。
試してみてください。あなたが何を作っているのかとても興味があります。 以下のコメントで共有するか、Twitterで私を見つけに来てください:@PaulieScanlon。