tech.guitarrapc.cóm

Technical updates

Azure Functions C#でNugetパッケージを利用してみた

さて、Azure Functionsの基本的な利用、GitHubやVSTSでのCIまで見てきました。

以前みた中で残っている、Azure Functionsを本番で利用できるようにする最後の砦が「外部ライブラリの利用」です。

https://tech.guitarrapc.com/entry/2016/04/02/070806#外部ライブラリの利用

外部ライブラリの利用。つまり、Node.jsでいうところのnpm、.NETでいうところのNuGetです。これができないと、標準ライブラリだけで頑張ることになり、できることが限られるので超重要です。

https://www.np.js .com/

https://www.nuget.org/

今回は、NuGetをAzure Functionsで利用する方法を見てみましょう。NuGetが利用できれば、C# にかぎらずF# やPowerShellでも利用できますからね。

ちなみにnpmはこの動画で! さくっとnpm installするだけです。

https://i.imgur.com/4DL1BWd.gif

Azure Functions での NuGet パッケージ定義

はじめにいいます。#r <PackageName>ではだめです。ちょっと工夫がいります。

ここではサンプルとして、GitHubが開発/公開しているOctokitをAzure Functionsで利用するようにしましょう。

https://www.nuget.org/packages/Octokit/

NuGet のバージョンを確認しておく

VS CodeやVisual StudioでNuGetを利用されたことがある方なら、NuGetパッケージのバージョン表記についてご存知でしょう。

Azure FunctionsでNuGetを利用するにあたり、当然ながら何をみてバージョンを指定とするか把握しましょう。

記事時点でOctokitの最新バージョンは 0.19.0、過去のバージョンは 0.18.0 という表記スタイルであることがわかります。

つまり、Octokitのバージョン指定は次の通りです。

パッケージ名 バージョン表記
Octokit 0.19.0

簡単ですね。これだけ把握していればokです。

project.json を作成して定義

ASP.NET 5や .NET Coreと同様に、Azure FunctionsでのNuGetパッケージの指定はproject.jsonを使います。

ただし、そのフォーマットはASP.NET 5とは違います。

https://github.com/aspnet/Home/wiki/Project.json-file

NuGetのproject.jsonフォーマットとなります。

https://docs.nuget.org/consume/ProjectJson-Intro

Octokit 0.19.0を指定するなら、以下のようなproject.jsonを作成します。どことなくnpmのフォーマットに近い...?

https://gist.github.com/guitarrapc/fe2303d0dee05f85805639285a478e5c

Azure Functionsは、Functionごとにフォルダが分離していることを説明しました。そこで、project.jsonをFunctionごとにフォルダ配置します。現時点では、project.jsonはVisual Studio OnlineやKudu、あるいはGit CIなどで配置することとなります。

project.jsonを配置すること*1で、project.lock.jsonが自動生成されます。ここを見るとNuGetパッケージが取り込まれたとわかります。

さぁ、これでなんとAzure FunctionsにおけるNuGetパッケージの定義は完了です。NuGetパッケージは、project.jsonで定義することで、自動的に作成したFunctionに取り込まれます。

そう、NuGet Packageに関しては、コード上で#r Octokit#r Octokitのようなことは不要です。というか、このようなファイル指定の読み込みはパッケージを不完全な形で取り込んでしまうのでやってはダメです。*2

あくまでも、#r <アセンブリ名>は、GACなどから必要なアセンブリ参照を追加するためと思えばいいでしょう。

お次は待ちに待ったコードです。

Function で NuGet パッケージを利用する

NuGet Pakckageを定義できたので、次はパッケージのライブラリを利用してみましょう。

Octokitを使って、リクエスト時に指定したownerownerowner一覧を取得してみます。

https://gist.github.com/guitarrapc/69ea2b31d83e2a2443e489797054eea5

Compileが通ります。

普通になんの支障もなくusing Octokit;をして、コードがかけていることがわかります。

あとは、入力に相当するサンプルjsonをおいて

https://gist.github.com/guitarrapc/56818a40768801a6b149a6e1f950e9d8

実行してみましょう。

Commit Id一覧が取れましたね! ばっちりです。

Chatwork への送信

では別のサンプルとして、Azure FunctionsからChatworkにメッセージを送信するため、Chatwork.ApiのNuGetパッケージを利用してみましょう。

https://www.nuget.org/packages/Chatwork.Api/

まずはproject.jsonを作成します。

https://gist.github.com/guitarrapc/887f4d194a238f8944aa38587319abb1

問題なくpackage.lock.jsonが生成されたらokです。

ではコードを書きましょう。一点注意なのは、Chawork.Apiは、#r "System.Threading.Tasks"の参照だけ追加で必要です。

https://gist.github.com/guitarrapc/421df29eef9f30ef2f566f807e462377

あとは、Request Bodyで、RoomIdRoomIdを指定します。今回はあえてSlackと語句を合わせてRoomIdRoomIdとしてjsonを受け取るようにしました。

https://gist.github.com/guitarrapc/42bd00917f1d29768e407991bebe3d52

実行して

メッセージが無事にChatworkに通知されましたね! ばっちりです。

補足

いくつか補足しておきましょう。

複数 dependencies の記述

npm同様、以下のようにすればokです。

https://gist.github.com/guitarrapc/e4a852a592ea17047cff54c41c40e3ef

すでに project.json を作った Function におけるpackage の差し替え

同じプロジェクトで使っているNuGetの追加や差し替えの時について補足しましょう。

packageの差し替え、追加はpackage.jsonを書き換えるだけでokです。これで自動的にpackage.lock.jsonが書き換わります。

CI

このように触っているとやはり、GitHubでのCIがベストかな、という印象です。表のGUIで指定できるといいんですけどね。

もしCIをする場合、Restoreを自動的にさせるため、Custom Scriptを利用してみてください。

https://github.com/fabiocav/webjobs-scripts-samples/tree/master/DeploymentScript

まとめ

さぁ、これでAzure Functionsに関する憂いはほぼ解消したので社内でしょうか? ぜひみなさんも試してください。

今回のサンプルも、リポジトリに追加しておいたのでご参考までにどうぞ。

https://github.com/guitarrapc/AzureFunctionsIntroduction

ドキュメントがなかったので苦労しました。 この記事を書き終えた後に、StackOverflowにNuGet利用についてスレッドが追加されました。

https://stackoverflow.com/questions/36411536/how-can-i-use-nuget-packages-in-my-azure-functions

Azure Functionsの神々に感謝です : thx @crandycodes, @paulbatum

*1:VS OnlineならSAVEしたタイミング

*2:やって痛い目に会いました。実行時エラーになります。