この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
いわさです。
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
にスタートアップ処理やルーティング設定が実装されています。
ここではハイライト部分を少しだけ修正していますが、ほぼデフォルト状態です。
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
)
Program.cs
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
:
こちらでは、インフラテンプレートなども含まれており、本エントリで実装したパッケージや追加コードなども含まれているのでそちらもぜひ利用してみてください。