API Gateway + Lambda で .NET 6 の Minimal API を実行してみる
いわさです。
AWS Lambda では .NET 6 がサポートされていますが、.NET 6 では Minimal API と呼ばれる、従来とは異なるAPIの実装方法が利用出来るようになっています。
Minimal API を使うと、.NET 上で不要な依存関係などを含まない最小限の Web API を作成することが出来ます。
今回、Minimal API をターゲットにした API Gateway を作成する機会がありましたので、構築の流れをご紹介します。
Minimal API の作成
dotnet new web
コマンドで作成されるものは最小限の Minimal API となっています。
本日はこちらを利用します。
% dotnet new web テンプレート "ASP.NET Core Empty" が正常に作成されました。 作成後の操作を処理しています... /Users/iwasa.takahito/work/hoge0717dotnet2/hoge0717dotnet2.csproj で ' dotnet restore ' を実行しています... Determining projects to restore... Restored /Users/iwasa.takahito/work/hoge0717dotnet2/hoge0717dotnet2.csproj (in 97 ms). 正常に復元されました。
従来のようなStartup.cs
やコントローラーは存在せず、以下のように Program.cs
にスタートアップ処理やルーティング設定が実装されています。
ここではハイライト部分を少しだけ修正していますが、ほぼデフォルト状態です。
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "hoge"); app.MapGet("/hoge1", () => "hoge1"); app.MapGet("/hoge2", () => "hoge2"); app.Run();
Lambda 用に最適化する
次に、Lambda で実行出来るようにコードを少し修正します。
今までもAWSから提供されている、Amazon.Lambda.AspNetCoreServer
を NuGet パッケージで導入することで、ASP.NET Core アプリケーションを Lambda 関数として実行することが出来ました。
今回の Minimal API でもこちらを使います。
このパッケージを導入すると、非 Lambda 関数向けに実装されている ASP.NET Core アプリケーションを Lambda 関数として実行することが出来ます。
しくみとしては、Amazon.Lambda.AspNetCoreServer
が API Gateway あるいは Application Load Balancer からのリクエストをネイティブな ASP.NET Core 用に変換し、レスポンスも同じように変換してくれます。そしてローカルで開発中は Kestrel で普通に動きます。最高に便利。
Amazon.Lambda.AspNetCoreServer.Hosting 追加
まずは、Amazon.Lambda.AspNetCoreServer.Hosting
をプロジェクトに追加します。
% dotnet add package Amazon.Lambda.AspNetCoreServer.Hosting --version 1.3.1 Determining projects to restore... Writing /var/folders/4d/nhd1bp3d161crsn900wjrprm0000gp/T/tmpMiFDFC.tmp : info : Committing restore... info : Writing assets file to disk. Path: /Users/iwasa.takahito/work/hoge0717dotnet/obj/project.assets.json log : Restored /Users/iwasa.takahito/work/hoge0717dotnet/hoge0717dotnet.csproj (in 7.63 sec).
サービスの追加
AddAWSLambdaHosting
メソッドを使ってサービスを追加します。
その際に、Lambda 関数のイベントソースを指定します。(RestApi
/HttpApi
/ApplicationLoadBalancer
)
var builder = WebApplication.CreateBuilder(args); builder.Services.AddAWSLambdaHosting(LambdaEventSource.RestApi); var app = builder.Build(); app.MapGet("/", () => "hoge"); app.MapGet("/hoge1", () => "hoge1"); app.MapGet("/hoge2", () => "hoge2"); app.Run();
Lambda用にバンドル
あとは Lambda用にモジュールをバンドルします。 今回は zipパッケージ化して Lambdaコンソールからアップロードします。
% dotnet publish -c Release --sc false -r linux-x64 .NET 向け Microsoft (R) Build Engine バージョン 17.0.0+c9eb9dd64 Copyright (C) Microsoft Corporation.All rights reserved. Determining projects to restore... All projects are up-to-date for restore. hoge0717dotnet -> /Users/iwasa.takahito/work/hoge0717dotnet/bin/Release/net6.0/linux-x64/hoge0717dotnet.dll hoge0717dotnet -> /Users/iwasa.takahito/work/hoge0717dotnet/bin/Release/net6.0/linux-x64/publish/ % cd /Users/iwasa.takahito/work/hoge0717dotnet/bin/Release/net6.0/linux-x64/publish/ % zip -r hoge0717dotnet.zip . updating: Amazon.Lambda.APIGatewayEvents.dll (deflated 53%) updating: Amazon.Lambda.RuntimeSupport.dll (deflated 62%) : updating: hoge0717dotnet.deps.json (deflated 78%) updating: Amazon.Lambda.AspNetCoreServer.dll (deflated 56%)
デプロイ先の Lambda を作成しデプロイパッケージをアップロード
Lambda 関数を作成します。
ランタイムは.NET 6 (C#/PowerShell)
で、dotnet publish
した際のアーキテクチャーにあわせるようにしましょう。
先程作成した zipパッケージをアップロードします。
最後に、ランタイム設定を編集しハンドラを設定します。
ここでは .NET モジュール名を設定します。
API Gateway と統合し、実行
Lambda関数の準備は完了しました。
あとは、API Gateway を統合して実行してみましょう。
先程のサービスパラメータにあわせて、REST APIを作成し、バックエンドに Lambda 関数を統合させます。
ここでは、Lambda プロキシ統合を有効化しています。
minimal API で設定したルートをリソース作成していきます。
ステージへデプロイ出来たら、HTTPクライアントを使ってリクエストを送信してみます。
% curl https://dx7a2kpxch.execute-api.ap-northeast-1.amazonaws.com/prd hoge % curl https://dx7a2kpxch.execute-api.ap-northeast-1.amazonaws.com/prd/hoge1 hoge1 % curl https://dx7a2kpxch.execute-api.ap-northeast-1.amazonaws.com/prd/hoge2 hoge2
おお、いけました。
さいごに
本日は、API Gateway + Lambda で .NET 6 の Minimal API を実行してみました。
今回は、もともと Lambda 用に構築されていなかった Minimal API を Lambda 化する流れを理解したかったので、標準テンプレートから新規作成し手動でモジュールアップロードをしました。
Lambda が最初からターゲットであれば AWS から .NET 用にAmazon.Lambda.Templates
というものが提供されていて、Minimal API のテンプレートも既に提供されています。
% dotnet new -i Amazon.Lambda.Templates 次のパッケージがインストールされます: Amazon.Lambda.Templates 成功: Amazon.Lambda.Templates::6.2.0により次のテンプレートがインストールされました。 テンプレート名 短い名前 言語 タグ ---------------------------------------------------- -------------------------------------------- ------- --------------------- Empty Top-level Function lambda.EmptyTopLevelFunction [C#] AWS/Lambda/Serverless Lambda Annotations Framework (Preview) serverless.Annotations [C#] AWS/Lambda/Serverless Lambda ASP.NET Core Minimal API serverless.AspNetCoreMinimalAPI [C#] AWS/Lambda/Serverless Lambda ASP.NET Core Web API serverless.AspNetCoreWebAPI [C#],F# AWS/Lambda/Serverless :
こちらでは、インフラテンプレートなども含まれており、本エントリで実装したパッケージや追加コードなども含まれているのでそちらもぜひ利用してみてください。