Vite + Netlify Functions でサーバーレス関数 ① Hello World

2021-10-09

Netlify Functions(以下、functions)の入門メモです。Vite (React, バニラJavaScript)のプロジェクトから使います。functions は背後で、AWS Lambda を使用していますが、AWSのアカウントもなし(Netlifyのアカウントは必要)で、サーバーの管理をおこなわずにサーバーでJavaScript(Node.js)やGoの関数をビルド、テスト、デプロイできます。

プロジェクトの生成

$ npx create-vite

以下のコマンドを実行し、適当なフォルダ名(vite-functions-hello としました)を指定し、framework は reactvariant vanilla を指定します。

最初のファンクション “Hello World”

  • プロジェクトのルートに netlify フォルダを作成し、その下に更に functions というフォルダを作成します。Netlify functions では指定しない場合、ここがデフォルトの functions のフォルダになります。
  • netlify\functions フォルダの下に hello.js ファイルを作成します。
exports.handler = async function(event, context) {
  return {
      statusCode: 200,
      body: JSON.stringify({message: "Hello World"})
  };
}

この状態で、devスクリプトを実行しても functions は実行されません。

ファンクションのデプロイ

  • 通常どおり、プロジェクトを git で管理します。
$ git init
$ git add .
$ git commit -m"Initial commit"
  • このあと、GitHub でリポジトリを作成し、コード一式を push します。※詳細省略
  • そのあと、NetilfyGitHub のリポジトリを指定してデプロイします。必要に応じてサイト名を変更します。※詳細省略

ファンクションの実行

  • 仮にデプロイしたサイトのURL https://vite-functions-hello.netlify.app/ (世界で唯一のあなたのサイトのURL)だとしたら、https://vite-functions-hello.netlify.app/.netlify/functions/hello にアクセスします。
    • パスの途中は、.netlify であって netlify でないことに注意します。
functions で Hello World
  • Hello world でました。簡単ですね。上記の6行ほどのコードで、APIのエンドポイントが作成できたことになります。背後ではAWS Lamda が使われています。
  • この場合、https://vite-functions-hello.netlify.app/ にアクセスすれば、違うものが表示されます。
  • Netlifyのダッシュボードの [Functions] を見ると functions がいつデプロイされたかや、そこをクリックするとログを見たりできます。
Netlifyのダッシュボードの Functions

Netlify CLIのインストールと開発サーバーの実行

Netlifyの本番環境で実行する functions をローカルでテスト可能とするために、まずは Netlify CLI をインストールします。

$ npm i netlify-cli --save-dev

次のコマンドで、Netlify CLI の使い方が表示されます。

$ netlify

package.jsondevスクリプトを追加します。

:
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "serve": "vite preview",
    "netlify": "netlify dev"
  },
:

これで次のコマンドにて、ローカル開発サーバーが起動され、http://localhost:8888/ がブラウザで表示されます。このあと、http://localhost:8888/.netlify/functions/hello にアクセスすると、https://vite-functions-hello.netlify.app/.netlify/functions/hello と同じ結果をローカルで確認できます。

フロントエンドからの functions の利用

現状、localhost:8888 にアクセスすると次が表示されていますが、”Hello Vite + React!”と表示されている部分を functions から取得した”Hello World”となるように変更してみたいと思います。

localhost:8888

functions からデータを取得するのに Fetch APIAxios (HTTPクライアント)を使ってもよいのですが、ここでは SWR (データ取得のための React Hooks ライブラリ)と Axios の組み合わせを使用します。

$ npm i swr axios
$ npm audit fix

まず、src\App.jsx より、カウンターに関するコードは削除し、最終的に次にしました。

import React from 'react';
import useSWR from 'swr';
import axios from 'axios';
import logo from './logo.svg';
import './App.css';

const fetcher = (url) => axios.get(url).then((res) => res.data);

const useGreeting = () => {
  const { data, error } = useSWR('/.netlify/functions/hello', fetcher);

  console.log (data);

  return {
    greeting: data?.message,
    isLoading: !error && !data,
    isError: error,
  };
};

const App = () => {
  const { greeting, isLoading, isError } = useGreeting();

  return (
    <div className='App'>
      <header className='App-header'>
        <img src={logo} className='App-logo' alt='logo' />
        {isLoading && <p>読込中...</p>}
        {isError && <p>読み込みエラー</p>}
        {greeting && <p>{greeting}</p>}
:
:

useSWRの第一引数のパスは、プロジェクトの相対パス(netlify\functions\hello.js)ではなくて、本番環境での相対パスであることに注意します。

functionsフォルダの変更

現在 hello.jsnetlify\functions フォルダにありますが、設定により任意のフォルダを使うことが可能です。

ルートフォルダの netlify.toml ファイルで次のように設定することにより、 functions フォルダの下のファイルが functions としてデプロイされるようになります。

[build]
  functions="functions"

環境変数の使用

functions で環境変数を使ってみます。これは、 functions を使う動機の一つにもなるのですが、APIのアクセスキーなどを隠すためにも functions を使用することができます。functions\hello.js を次のように変更します。

exports.handler = async function (event, context) {
  return {
    statusCode: 200,
    body: JSON.stringify({ message: process.env.SECRET_GREETING }),
  };
};

そして、ルートフォルダに .env ファイルを作成します。

SECRET_GREETING=どうもこんばんは。ピータンです。

.ignore ファイルに以下の行を追加します。

.env

この状態でのデプロイ結果はこちらです。GitHubはこちら。