テクノロジー

ZEIT Nowによるサーバーサイド開発 ③サーバーレス関数の作成

ホーさん's icon'
  • ホーさん
  • 2020/04/05 22:12
Content image

サーバーレスでWebアプリを作ろうとするときによく私が使うZeit NowというWebサービスを使ったサーバーサイド開発(簡単なAPIの作り方)のはじめ方について全3記事で説明します。前回の記事では、Expressを用いたAPIの開発について説明しました。本記事では、ZEIT Nowの機能を使ってサーバーレス関数を作っていきます。

(例によってALIS Boot Campで度々説明が必要になるので参考資料です)

記事の目次はこちらです。

① ZEIT Nowへの登録
② Expressを用いたAPIの立ち上げ
③ サーバーレス関数の作成(本記事)

1. サーバーレス関数とは

サーバーレス開発では、クラウドを使ってサービスを立ち上げますので、使ったリソース分だけお金がかかります。なので、CPUやメモリなどについて最低限の計算リソースで処理を実行することが非常に重要になります。AWSのAWS LambdaやGCPのCloud Functionsは、関数(Lambda関数と呼ばれます)の実行のために最低限必要なリソースを自動で割り当ててくれるFaaS(Function as a Service)と呼ばれるサービスで、サーバーレス開発ではよく使われます。前回の記事でAPIについて説明しましたが、1回のAPIへのリクエストが1回のLambda関数の実行に対応しており、各リクエストに対して計算リソースが割り当てられ、関数が処理されて結果が返されます。リクエストがない(アクセスがない)時には一切課金されません。このリソースの柔軟性が、FaaSが好まれる理由です。ZEIT Nowにもこのような仕組みがあり、AWS Lambdaのようにサーバーレスな関数を作ることができます。

参考文献:サーバーレスのメリット&本質を、AWS Lambdaを使って理解しよう

 

2. Nowを使ったサーバーレス開発

それでは早速作っていきましょう。前回と同様、適当なディレクトリを用意します。

mkdir api-sample-now
cd api-sample-now

次に、前回の記事と同じようにpackage.jsonを作り、expressとnode-fetchをインストールします。

npm init
npm install express node-fetch

package.jsonの例としては以下のような感じです。

{
    "name": "お好きなプロジェクト名",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "",
    "license": "ISC",
    "dependencies": {
        "express": "^4.17.1",
        "node-fetch": "^2.6.0"
    }
}

次に、now.jsonというZEIT Nowの設定ファイルと作ります。以下のように書きます。

{
    "version": 2,
    "name": "お好きなプロジェクト名",
    "builds": [
        { "src": "api/**/*.js", "use": "@now/node" }
    ]
}

"version"は、Nowのバージョンを指定します。最新は2です。v1.0は、もうすぐデプロイができなくなり、2020年8/7には今デプロイされているプロジェクトも全て削除されることが2020年4月にアナウンスされました。

"name"はプロジェクト名を指定します。

"builds"ではそのファイルをどの言語でビルドするかを指定します。"src"はビルドするソースファイルで、"api/**/*.js"はファイルがある場所をワイルドカードを使って指定してます。"use" は使用するビルダを指定することができ、今回は@now/nodeを使用します。

前回の記事ではapp.jsに全てのAPIをapp.jsに書き込んでいました。Lambda関数では、各APIを別々のファイルに保存します。ファイルの場所が、先ほどnow.jsonで指定した"src"の"api/**/*.js"に対応しています。

まず準備として、app.jsという名前のファイルを用意し、以下のように書きます。

const exp = require("express");
const app = exp();
module.exports = app;

最初の2行は前回の記事でapp.jsに書き込んだものと同じ、expressのモジュールのインポートとインスタンス化に関する部分です。最後の1行は、インスタンスを他のファイルから読み込みできるようにしています。app.listen()に相当する部分はNowが自動でやってくれるので必要ありません。これを適当な場所(今回はutil/app.js)に置きましょう。

次に、apiというディレクトリを作り、さらにその中にhello-worldというディレクトリを作りましょう。最後にhello-worldのディレクトリ内にindex.jsという名前でファイルを作ります。中身は以下のようにします。

const app = require("../../util/app");

app.get("*", (req, res) => {
    res.send("hello world!");
});

module.exports = app;

一行目は、先ほど作成したutil/app.jsからエクスポートしたappインスタンスを読み込んでます。

app.get()の部分は前回の記事で説明したものと同じですが、前回の記事ではapp.get()の第一引数が"/hello"という文字列でAPIのアクセス先(エンドポイント)を指定していたのに対して、今回はエンドポイントを”ファイルの場所”で設定しており(api/hello-world/index.js)、app.get()の第一引数が"*"であることが違いです。また、最後の行でappインスタンスをmodule.exportsで書き出すのも必須なのでご注意下さい。

現在のファイル構成は以下のような感じです。

api-sample-now
├── api
│   └── hello-world
│       └── index.js
├── now.json
├── package.json
├── package-lock.json
├── node_modules
└── util
   └── app.js

それではひとまずこの最小構成でデプロイしてみましょう。まずは、api-sample-nowのディレクトリ内で、以下のコマンドを実行します。

now

nowのコマンドを使うには、こちらの記事でZEIT Nowへのユーザー登録とCLIのインストールを行う必要があります。

以下のようなメッセージが出たらOKです。これで、nowのアカウントと現在のディレクトリがリンクされます。

Now CLI 17.1.1

🔍  Inspect: https://zeit.co/ユーザー名/プロジェクト名/96zge3abt [2s]

✅  Preview: https://プロジェクト名.ユーザー名.now.sh [copied to clipboard] [7s]

📝  To deploy to production (プロジェクト名.now.sh), run `now --prod`

次に、ローカルで動かしてみましょう。

now dev

以下のようなメッセージが出ればOKです。(Ctrl+Cでアプリが停止されます)

> Ready! Available at http://localhost:3000

http://localhost:3000に続けて、Lambda関数のファイル場所である/api/hello-worldを繋げると、そのLambda関数を実行できます。

http://localhost:3000/api/hello-world

ブラウザからアクセスしてhello worldという文字列が出たら成功です。

無料版では、1日に本番環境へデプロイできる回数には100という制限があるため、ZEIT Nowで開発するときは、now devを使ってローカルでテストすることをお勧めします。

Content image
https://zeit.co/pricing

次に、前回の記事でも追加した/api/opensea-assetsのAPIを追加してみましょう。apiディレクトリ内にopensea-assetsという名前のディレクトリを作成し、その中にindex.jsというファイルを作ります。

現在のファイル構成は以下のような感じです。

api-sample-now
├── api
│   └── hello-world
│       └── index.js
│   └── opensea-assets
│       └── index.js
├── now.json
├── package.json
├── package-lock.json
├── node_modules
└── util
   └── app.js

api/opensea-assets/index.jsのファイルの中身は以下のようにします。

const app = require("../../util/app");
const { parse } = require("url");
const fetch = require("node-fetch");

app.get("*", (req, res) => {

    const { query } = parse(req.url, true);
    const { owner } = query;

    const url = `https://rinkeby-api.opensea.io/api/v1/assets/?owner=${owner}&format=json`    
    
    fetch(url)
        .then((result) => result.json())
        .then((data) => {
            res.send(data);
        })
        .catch(() => {
            res.status(401).end();
        });

});

module.exports = app;

app.get()の第一引数が"*"であること、最後の行のmodule.exports = app;にご注意ください。保存できたら、now devで動作確認します。

http://localhost:3000/api/opensea-assets?owner=0x9ba9105d4a1cde23fa2ae25c67dea928b975d729

動作確認ができたら、本番環境にデプロイしてみましょう。nowコマンドを--prodオプションをつけて実行します。

now --prod

成功すると、

✅  Production: https://プロジェクト名.now.sh [copied to clipboard] [23s]

のようなProduction: に続くアドレスがメッセージに出てきますので、

https://プロジェクト名.now.sh/api/hello-world

にアクセスすると、本番環境で動いているのがわかるかと思います。また、ZEIT Nowのダッシュボードでもステータスの確認ができます。

以上です。お疲れさまでした。

 

おわりに

簡単ですが、サーバレス関数をAPIとしてZEIT Nowにデプロイする手順について説明しました。手順通りに進めれば非常に簡単にできますが、サーバレス関数を全く知らないとnow.jsonの設定の仕方やフォルダ構成など、結構詰まる箇所が多いと思います。今回3回に分けて、なるべく初心者にも「まずはとりあえず動かしてみる」ことができるように意識して記事を執筆しました。この記事がどなたかのお役に立ちましたら幸いです。

 

クレジット(画像素材):

 

Supporter profile iconSupporter profile icon
Article tip 2人がサポートしています
獲得ALIS: Article like 78.05 ALIS Article tip 611.00 ALIS
ホーさん's icon'
  • ホーさん
  • @fukurou
Python/JavaScript

投稿者の人気記事
コメントする
コメントする
こちらもおすすめ!
Eye catch
テクノロジー

iOS15 配信開始!!

Like token Tip token
7.20 ALIS
Eye catch
クリプト

Uniswap v3を完全に理解した

Like token Tip token
18.92 ALIS
Eye catch
テクノロジー

オープンソースプロジェクトに参加して自己肯定感を高める

Like token Tip token
85.05 ALIS
Eye catch
クリプト

約2年間ブロックチェ-ンゲームをして

Like token Tip token
61.20 ALIS
Eye catch
ゲーム

ドラクエで学ぶオーバフロー

Like token Tip token
30.10 ALIS
Eye catch
クリプト

Bitcoinの価値の源泉は、PoWによる電気代ではなくて"競争原理"だった。

Like token Tip token
159.32 ALIS
Eye catch
クリプト

Bitcoin史 〜0.00076ドルから6万ドルへの歩み〜

Like token Tip token
947.13 ALIS
Eye catch
クリプト

NFT解体新書・デジタルデータをNFTで販売するときのすべて【実証実験・共有レポート】

Like token Tip token
121.79 ALIS
Eye catch
テクノロジー

なぜ、素人エンジニアの私が60日間でブロックチェーンゲームを制作できたのか、について語ってみた

Like token Tip token
270.93 ALIS
Eye catch
クリプト

17万円のPCでTwitterやってるのはもったいないのでETHマイニングを始めた話

Like token Tip token
46.60 ALIS
Eye catch
テクノロジー

彼女でも分かるように解説:ディープフェイク

Like token Tip token
32.10 ALIS
Eye catch
クリプト

ジョークコインとして出発したDogecoin(ドージコイン)の誕生から現在まで。注目される非証券性🐶

Like token Tip token
38.31 ALIS