ほりひログ

所属組織の製品 (Azure とか) に関連する内容が多めだけど、個人の見解であって、所属組織を代表する公式情報ではないです。

Azure Functions ⚡ 上で Deno 🦕 を使う denofunc を試してみた + おまけ

denofunc

denofunc は Azure Functions の PM である Anthony ChuOSS で公開している、Deno を Azure Functions で動かすためのユーティリティーです。

github.com

カスタム ハンドラーの仕組みを使っています。

今のところ、Deno v1.0.2 での動作が確認されています (v1.0.3 では動きません)。

やってみる

ほぼ全て README.mdに書いてあることなんですが。

インストール

事前に Azure CLIAzure Functions Core Tools が必要です。
ローカル実行時やデプロイ時に、内部で使用しています。

インストールには、Deno に備わっている、スクリプトをコマンド化する機能を使います。
下記のコマンドです。

$ deno install --allow-run --allow-read --allow-write --allow-net --unstable -f -n denofunc https://deno.land/x/azure_functions/denofunc.ts
Download https://deno.land/x/azure_functions/denofunc.ts
Download https://deno.land/x/azure_functions/deps.ts
#  (略)
Download https://deno.land/std@0.51.0/bytes/mod.ts
Compile https://deno.land/x/azure_functions/denofunc.ts
✅ Successfully installed denofunc
/home/horihiro/.deno/bin/denofunc

インストールに成功すると、 denofunc というコマンドが Deno と同じディレクトリに作成されるので、パスが通っているはずです。 f:id:horihiro:20200606123335p:plain

実行してみると、おなじみのロゴが表示されます。 f:id:horihiro:20200606123112p:plain

プロジェクトの作成

サブコマンド init でプロジェクトの初期ファイルが作成されます。

$ denofunc init
Initializing project...
./.devcontainer
./.devcontainer/devcontainer.json
./.devcontainer/Dockerfile
./.gitignore
./.tours
./.tours/welcome-to-deno-azure-functions.tour
./.vscode
./.vscode/extensions.json
./deps.ts
./functions
./functions/hello_world.ts
./functions/queue_trigger.ts
./host.json
./local.settings.json
./worker.ts

HTTP トリガー関数 hello_world と Queue トリガー関数 queue_trigger の実装が含まれています。
# ただしこのまま実行した場合、有効なのは hello_world だけです。

中身はこちらのリポジトリーです。

github.com

ローカル実行

funcion.json はどこにも見当たりませんが、とりあえずおもむろに denofunc start してみます。

f:id:horihiro:20200606201525p:plain

関数コードが Deno 内の tsc 経由でトランスパイルされ、Azure Functions Core Tools が立ち上がります。
実行前にはなかった function.json ですが、denofunc が各関数コードの実装 (export されている metadata プロパティ) から function.json を作ってくれました。

hello_world (HTTP トリガー関数) にアクセスしてみると、正常に動作しました。 f:id:horihiro:20200606201805p:plain

関数を追加してみる

./functions ディレクトリーに、ts ファイルを追加します。

import { AzureFunctionsContext } from "../deps.ts";

export default {
  // Imprementation of the function
  handler: async function handler(context: AzureFunctionsContext) {
    // 関数の実装
  },

  // Name of the function
  name: "abc_func",

  // metadata (= function.json) of the function
  metadata: {
    "bindings": [
      :
    ]
  }
};

次に ./worker.ts に作った関数を読み込むためのコードを追加します。

import { AzureFunctionsWorker } from "./deps.ts"

import hello_world from "./functions/hello_world.ts";
//import queue_trigger from './functions/queue_trigger.ts';
import abc_func from "./functions/abc.ts";  // <-- 追加

const worker = new AzureFunctionsWorker([
  hello_world,
  //queue_trigger,
  abc_func  // <-- 追加
]);

await worker.run();

こはちょっとだけ手間ですね。

Azure Functions へデプロイ

事前に Azure 上に Function App をデプロイしておく必要があります。
denofunc の今の実装は、Linux の Comsumption プランを対象としているようです。

denofunc publish <Function App 名> の書式でコマンドを実行すると、Azure Functions Core Tools が関数コードなどを zip デプロイします。

f:id:horihiro:20200606203126p:plain

カスタム ハンドラーなので、Deno のランタイムを同梱しないといけません。
denofunc は、linux のバイナリーをダウンロードしていました。

hello_world 関数を実行してみると、ローカル実行と同じ結果が返ってくるので、正常にデプロイできているようです。

f:id:horihiro:20200606203704p:plain

おまけ

前のエントリーで紹介した Deno のバージョン切り替えスクリプト dvm.shdenobrew になりました。

github.com

コッソリバグつぶしたり、サブコマンド増やしたりして、改善をしています。