tech.guitarrapc.cóm

Technical updates

.NET Core on Lambda で nuget パッケージを利用してみた

といいつつ、当初から Json.NET を利用しているのですが、そこはおいておきましょう。

今回は、AWS Lambda で nuget パッケージを利用してみます。とはいっても難しいことは何もなく、通常の.NET Core アプリと同様です。

Azure Fucntions とは少し違うのでそのあたりも見てみましょう。

tech.guitarrapc.com

目次

必要な条件

.NET Core 対応です。具体的には以下が現状の条件になっています。

compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0)

ということはつまり、.NET Core 1.0 か .NET Standard 1.6 がいけるということです。

The arrows indicate that the platform supports a higher version of .NET Standard. For instance, .NET Core 1.0 supports the .NET Standard version 1.6, which is why there are arrows pointing to the right for the lower versions 1.0 – 1.5.

dotnetcore.gaprogman.com

ざっくりいうと、project.json に以下の記述がされている nuget packge が互換性があるパッケージとなります。

gist.github.com

gist.github.com

例えば Json.NET は次のようになっています。さすが Json.NET は難しい...。

https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/project.jsongithub.com

ダメなパッケージの例

一見 .NET Core 行けてそうでダメなものが結構出会います。例えば Octokit がそうです。

www.nuget.org

さて、.NET Core 4.5? .NET Core と書いてあるからといって同じではないのです。

エラーが明確に原因を示しています。

    Package Octokit 0.23.0 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package Octokit 0.23.0 supports:
      - net45 (.NETFramework,Version=v4.5)
      - netcore451 (.NETCore,Version=v4.5.1)
      - portable-net45+win8+wp8+wpa81 (.NETPortable,Version=v0.0,Profile=Profile259)
    Package Microsoft.Net.Http 2.0.20505 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package Microsoft.Net.Http 2.0.20505 supports: net40 (.NETFramework,Version=v4.0
)
    One or more packages are incompatible with .NETCoreApp,Version=v1.0.

Github で project.json を見てみると....?

https://github.com/octokit/octokit.net/blob/master/Octokit.Next/project.jsongithub.com

いけそうですが、残念です。

適当にビルドして参照しようとしても、現状の .NET Core では、nuget からの取得になるようです。

github.com

ということはつまり、VSTSやMyGetのようなプライベートNuget feed を利用するか、local folder から Nuget feed を配信すればいけるようですがそれはまたの機会に。

stackoverflow.com

Chatworkに送信する

Azure Functions でやったように Chatwork にメッセージ送信してみましょう。

.NET Core 対応していないライブラリの対応

Chatwork.Api という いつも使っている nuget パッケージがありますが、昨日まで 0.4.0 で .NET Core 対応されていませんでした。

www.nuget.org

このままでは project.json で 0.4.0 を指定しても当然利用できません。

    Package Chatwork.Api 0.4.0 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package Chatwork.Api 0.4.0 supports: portable-net45+win8+wp8+wpa81 (.NETPortable,Version=v
0.0,Profile=Profile259)

    One or more packages are incompatible with .NETCoreApp,Version=v1.0.

さっそく .NET Core 対応する PR を送ったところ、id:tanaka733 さんが素早く対応してくださいました。心から感謝なのです。

github.com

Json.NET をはじめとしていくつかのライブラリでどうやって対応しているのかとみてみましたが、ソリューション .sln を分割して、.xproj を改めて作成というパターンが多いのですね.... PCL から .NETStandard 1.6 へのコンバートかと思いましたが意外でした。クロス対応パッケージの作成には苦労しそうですが、今回は .NET Standard 1.6 にすることになりました。

これにより、0.5.0 がリリースされ .NET Standard 1.6 ベースになりました。

www.nuget.org

ライブラリの利用

もちろん新しくなった Chatwork.Api は .NET Core でも利用できるようになっています。project.json に指定してみましょう。

ばっちりですね。

早速コードを書いてみましょう。

今回は、API Gateway から AzureFunctions 同様に以下のフォーマットの JSON が飛んで来たら送信するようにします。

gist.github.com

Azure Functions では次のコードでした。

gist.github.com

AWS Lambda on .NET Core では次のようになります。事前にシリアライズされるか程度で、コードはほぼ変わりません。

gist.github.com

テストも通り、

ローカル実行でもブレークポイントが貼れています。

では VSからデプロイしてみましょう。環境変数に ChatworkApiKey をキーにApiキーを埋め込みます。

サンプルJSON を与えて実行してみると、テスト同様に飛びました。無事に成功です。

もちろん、Channel に誤った数値を入れれば権限がないことを教えてくれます。

{
  "errorType": "AggregateException",
  "errorMessage": "One or more errors occurred. (Failed with code Forbidden. Message: {"errors":["You don't have permission to send messages in this room"]})",
  "stackTrace": [
    "at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)",
    "at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)",
    "at lambda_method(Closure , Stream , Stream , ContextInfo )"
  ],
  "cause":   {
    "errorType": "Exception",
    "errorMessage": "Failed with code Forbidden. Message: {"errors":["You don't have permission to send messages in this room"]}",
    "stackTrace": [
      "at Chatwork.Service.ChatworkClient.<SendAsync>d__33`1.MoveNext()",
      "--- End of stack trace from previous location where exception was thrown ---",
      "at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)",
      "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)",
      "at SendToChatwork.Function.<FunctionHandler>d__1.MoveNext()"
    ]
  }
}

まとめ

無事に .NET Core なパッケージが扱えることが確認できました。まだまだ .NET Core 対応のライブラリは少ないですが、今後盛んになると祈っています。

今回のサンプルも Github に置いておきます。

github.com