白眼鏡のblog

新しく得た知見を備忘録的に書き連ねていく

Firebase Cloud Functionsで動かすjson-server TypeScript編

アプリ開発をやっていると、サーバ側はまだ出来上がってないけど、アプリだけでサーバからのAPIレスポンスを受け取った時の挙動を確認したい
といったことは稀によくあるのかなと思います。
というわけで、今回はjson-serveerを使って作ったRestAPIのモックをFirebase Cloud Functionsを使って公開してみた話について書いていきます。

FirebaseProject作成

(Node.jsの環境が整っていることが条件です)
まずは、FirebaseCLIを導入します。

$ npm install -g firebase-tools

ダウンロードが完了したら、Firebaseへログインします。

$ firebase login

実行すると、ブラウザに遷移してログインを求められます。
ログインして、権限を承認するとコマンドラインからfirebaseが使えるようになります。

コンソールに戻り、プロジェクトフォルダを作成します。

$ mkdir firebase_function
$ cd firebase_function

プロジェクトフォルダに入ったらfirebaseプロジェクトの初期化を行います。

$ firebase init

デフォルトのプロジェクトなど聞かれるので、すでに作成していればそれを
していなければcreateを選択します。
ここで、TypeScriptを使うかどうかも聞かれたはずなので、TypeScriptを選択します。
これでプロジェクト作成は完了です。

json-serverの初期化

まずは、functionsディレクトリに移動します。
ここにレスポンスとなるJsonファイルを作成します。
ファイル名はわかればなんでもOK。
stub.json

{
"items": [
    { 
        "id": 1, 
        "title": "json-server", 
        "message": "hoge" 
    }
  ],
  "descriptions": [
    { 
        "id": 1,
        "body": "hoge,hoge
    }
  ]
}

レスポンスになるjsonの定義は以上です。

次に、functions/src/へ移動します。
移動後に次のコマンドを実行し、json-serverをインストールします。

$ cd src
$ npm install json-server

index.tsを次のように編集します。

import * as functions from 'firebase-functions';
import * as jsonServer from 'json-server';

const server = jsonServer.create();
const router = jsonServer.router('stub.json');
const middlewares = jsonServer.defaults();

server.use(middlewares);
server.use(router);

export const mock = functions.https.onRequest(server);

読み込むJsonファイルの場所に関してですが、ビルド後にできる場所を刺しておく必要があります。
そのため、ここでは../stub.jsonではなく、stub.jsonとしています。 ここまでできたら、あとはビルドしてデプロイするだけです。
コマンドを実行します。

$ npm run build
$ npm run deploy

そうすると
✔ Deploy complete!

Project Console: https://xxxxx.xxxx.xxxx.xxx/overview
のように表示されます。
これでjson-serverをCloudFunctionsを通してアクセスできるようになりました。

GET以外のHTTP Methodへの対応

あくまでスタブとしての運用をする場合、どのメソッドが入ってきたとしても、特定の値を返却したい
ということはあるかと思います。
ここまでで説明してきた設定のままPOSTなどを実行すると、jsonファイルに値が書き込まれてしまい想定通りのレスポンスが受け取れません。
そのため、GET以外のMethodが入ってきた場合、全て握りつぶし、GETとして扱うという処理を追記します。

index.ts

import * as functions from 'firebase-functions';
import * as jsonServer from 'json-server';

const server = jsonServer.create();
const router = jsonServer.router('stub.json');
const middlewares = jsonServer.defaults();

server.use(middlewares);

server.use(function (request, response, next) {
    if (request.method !== 'GET') {
        request.method = 'GET'
    }
    next()
})

server.use(router);

export const mock = functions.https.onRequest(server);

これで、テストで使うためという面では最低限の機能が提供できるものが出来上がるかと思います。