tech.guitarrapc.cóm

Technical updates

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

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

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

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

https://tech.guitarrapc.com/entry/2016/04/05/043723

必要な条件

.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.

https://dotnetcore.gaprogman.com/2016/11/24/net-standard-what-it-is-and-how-it-applies-to-net-core/

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

https://gist.github.com/guitarrapc/781935217758ebd41ffe9202c983e0a5

https://gist.github.com/guitarrapc/2d729785be387e95501508d8ed4c8566

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

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

ダメなパッケージの例

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

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

さて、.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.json

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

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

https://github.com/aspnet/Home/issues/1672

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

http://stackoverflow.com/questions/38183649/net-core-1-0-visual-studio-referencing-external-dll

Chatworkに送信する

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

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

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

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

このままでは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さんが素早く対応してくださいました。心から感謝なのです。

https://github.com/tanaka-takayoshi/CSharp.Chatwork.Api/pull/21

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

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

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

ライブラリの利用

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

ばっちりですね。

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

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

https://gist.github.com/guitarrapc/9e7f7082ec3a62b7a9c830c27d45e493

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

https://gist.github.com/guitarrapc/349e662a879bd3fe33bf4fe3ef366742

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

https://gist.github.com/guitarrapc/930d4e9deacd78ec270884833fddb53e

テストも通り、

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

では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に置いておきます。

https://github.com/guitarrapc/AWSLambdaCSharpIntroduction