Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

Azure Functions を TypeScript でやってみた「ハローワールドから Durable Functions まで」

$
0
0

2019/02/25 くらいに出た Azure Functions Core Tools の 2.4.401 のリリースノートに

- Add TypeScript templates

の文言が。

これは試すしかないでしょう。ということでアップデートして func initしてみます。

C:\Users\kaota\Documents\Labs\TSFunc\Hello>func init
Select a worker runtime: node
Select a Language:
javascript
typescript

typescript がちゃんとある。typescript を選択すると package.json には以下のような devDependencies が追加されて

"devDependencies": {"@azure/functions": "^1.0.1-beta1",
    "typescript": "^3.3.3"
  }

さらには tsconfig.json も生成されます。

{"compilerOptions": {"module": "commonjs",
    "target": "es6",
    "outDir": "dist",
    "rootDir": ".",
    "sourceMap": true,
    "strict": false}}

npm installしておきます。

func newで HttpTrigger を選ぶとちゃんと index.ts が追加されました。

import{ AzureFunction, Context, HttpRequest }from"@azure/functions"const httpTrigger: AzureFunction =asyncfunction(context: Context, req: HttpRequest): Promise<void>{
    context.log('HTTP trigger function processed a request.');const name =(req.query.name ||(req.body && req.body.name));if(name){
        context.res ={// status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)};}else{
        context.res ={status: 400,
            body: "Please pass a name on the query string or in the request body"};}};exportdefault httpTrigger;

そして生成された HttpTrigger の function.json を見てみるとこうなってます。

{"disabled": false,
  "bindings": [{"authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": ["get",
        "post"
      ]},
    {"authLevel": null,
      "type": "http",
      "direction": "out",
      "name": "res",
      "methods": null}],
  "scriptFile": "../dist/Hello/index.js"
}

なるほど、scriptFile で dist フォルダーの下に作られるコンパイル後の JavaScript を見るようにしてるんですね。ということで npm run buildをするか、npm run watchをしてビルドをします。

そうすると dist フォルダーに js が生成されます。あとは func host startをするとローカルで動くのでアクセスしてみましょう。

動いた!!

f:id:okazuki:20190228130209p:plain

Durable Functions も試してみる

ハローワールド動いたので次は、個人的に Azure Functions のキラーコンテンツだと思ってる Durable Functions を試してみます。これが動かないと始まらない。 とりあえず以下のページを参考に…

github.com

docs.microsoft.com

まず下準備

func extensions install -p Microsoft.Azure.WebJobs.Extensions.DurableTask -v 1.7.0
npm install durable-functions

node_modules の下の durable-functions を見てみたらちゃんと .d.tsもありますね!

f:id:okazuki:20190228130712p:plain

func newにも、ちゃんと Durable 系のテンプレートが入ってます。いいね。

f:id:okazuki:20190228130831p:plain

ということで Starter と Orchestrator と Activity を適当に作ります。

f:id:okazuki:20190228131002p:plain

インテリセンス出る。まじ神

f:id:okazuki:20190228131236p:plain

ということで、こんな感じに Starter を調整して

import * as df from"durable-functions"import{ AzureFunction, Context, HttpRequest }from"@azure/functions"const httpStart: AzureFunction =asyncfunction(context: Context, req: HttpRequest): Promise<any>{const client = df.getClient(context);const instanceId =await client.startNew('Orchestrator',undefined, req.body);

    context.log(`Started orchestration with ID = '${instanceId}'.`);return client.createCheckStatusResponse(context.bindingData.req, instanceId);};exportdefault httpStart;

Orchestrator もこんな感じに

import * as df from"durable-functions"const orchestrator = df.orchestrator(function* (context){const outputs =[];

    outputs.push(yield context.df.callActivity("Activity1","Tokyo"));
    outputs.push(yield context.df.callActivity("Activity2","Seattle"));return outputs;});exportdefault orchestrator;

Activity 関数はこんな感じ。

import{ AzureFunction, Context }from"@azure/functions"const activityFunction: AzureFunction =asyncfunction(context: Context): Promise<string>{return`Hello ${context.bindings.name} from Activity1!`;};exportdefault activityFunction;

ではビルドしたら実行しようと思ったのですが以下のエラーが。

node_modules/durable-functions/lib/src/utils.d.ts:1:23 - error TS2688: Cannot find type definition file for 'node'.
node_modules/durable-functions/lib/src/utils.d.ts:8:56 - error TS2503: Cannot find namespace 'NodeJS'.

dist に js は生成されてるからビルドは出来てるけど気持ち悪いのでとりあえず以下のコマンドをうったら消えた。

npm i -d @types/node

Azure Storage Emulator を起動して func host startします。

Azure Storage Emulator は最新にしましょう。少し古いやつだと何か問題が起きた記憶。

そうするとエラーが出ました。

[2019/02/28 4:20:44] A host error has occurred
[2019/02/28 4:20:44] Microsoft.WindowsAzure.Storage: Settings must be of the form "name=value".
Settings must be of the form "name=value".

そういえば local.settings.json に Azure Storage の接続文字列が初期状態では設定されてないんでした。エミュレーター用の接続文字列をとりあえず追加します。

こんな感じで

{"IsEncrypted": false,
  "Values": {"FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureWebJobsStorage": "UseDevelopmentStorage=true"
  }}

あ、あと func host start以外にも npm run startnpm run start:hostとかでも OK。 何やってるかは package.jsonにあります。

起動したら Starter のエンドポイントを叩くとばっちり動きます。

f:id:okazuki:20190228132921p:plain

statusQueryGetUri を叩くと以下の JSON が返ってきました。

{"instanceId":"28038e30463544ab965db44f9c9ccb1e",
  "runtimeStatus":"Completed",
  "input":null,
  "customStatus":null,
  "output":["Hello Tokyo from Activity1!","Hello Seattle from Activity2!"],
  "createdTime":"2019-02-28T04:28:54Z",
  "lastUpdatedTime":"2019-02-28T04:28:56Z"
}

ばっちりですね。適当に Azure に Function App を作ってデプロイもしてみました。とりあえず試すだけなら以下のコマンドで

func azure functionapp publish <作った Function App の名前>

デプロイされました。関数もちゃんと認識されてます。

f:id:okazuki:20190228133603p:plain

叩いてみると無事動いた動いた。めでたい。

{"instanceId":"03e27dc7db234991bead2ea369173963",
  "runtimeStatus":"Completed",
  "input":null,
  "customStatus":null,
  "output":["Hello Tokyo from Activity1!","Hello Seattle from Activity2!"],
  "createdTime":"2019-02-28T04:36:16Z",
  "lastUpdatedTime":"2019-02-28T04:36:26Z"
}

まとめ

これで Azure Functions の node のほうで開発するときに手軽に TypeScript 始めることが出来るようになりました。 TypeScript 好きな人も是非 Azure Functions 使ってみてね!


Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>