備忘録

備忘録

C# + AWS Lambda + API Gateway

注意

この記事の内容は2017年3月10日時点の物です。
内容が古くなっている場合があります。

Ⅰ. はじめに

タイトルの通りですが、 AWS LambdaC#を動かし、エンドポイントにAmazon API Gatewayを使う方法です。

f:id:kagasu:20200423035625p:plain

Ⅱ. ゴール

身長体重を受け取り、BMI理想体重を出力するAPIを作成することをゴールとします。

(画像のツールはPostmanです) f:id:kagasu:20200423035633p:plain

Ⅲ. 前提条件

Ⅳ. 手順(AWS Toolkit for Visual Studioを利用する方法)

Windows 上で動作する VisualStudio が必要です。
Visual Studio CodeVisualStudio for MacJetBrains Rider はこの記事を書いた時点ではサポートされていませんでした。
アドオンなども記事を書いた時点ではありませんでした。

1. AWS Toolkit for Visual Studioをインストールする

ダウンロード、インストールを完了させてください。
https://aws.amazon.com/jp/visualstudio/

2.プロジェクトを作成する

AWS Lambda Project (.NET Core) を選択 して、プロジェクトを作成して下さい。
f:id:kagasu:20200423035640p:plain

3. Empty Functionを選択

今回は簡単な計算アプリケーションの為、Empty Functionを選択します。 f:id:kagasu:20200423035647p:plain

4. dotnet restoreする

プロジェクトディレクトリを開き以下のコマンドをコマンドプロンプトで実行します。
※2017/03/10追記
Visual Studio 2017では dotnet restoreをコマンドプロンプトで行う必要が無くなりました。

dotnet restore

Restore completed と表示されればOKです。

<s>この手順は AWS Lambda のプロジェクト作成に限らず、
.NET Core プロジェクトを作成した後に必ず必要な手順です。
NuGet からインストール、アンインストールした場合や、
参照の追加、削除した場合にも必ず必要になります。

めんどくさいですね。
誰か良い物作って下さい(他力本願)</s>

f:id:kagasu:20200423035656p:plain f:id:kagasu:20200423035702p:plain f:id:kagasu:20200423035707p:plain

5. プログラムを書く

VisualStudio に戻り以下のプログラムをコピペして下さい。
API Gatewayの統合リクエストの仕様に合わせたサンプルとなっています。
namespace は 適宜合わせて下さい。

Function.cs

using System;
using System.Collections.Generic;
using System.Net;
using Amazon.Lambda.Core;
using Newtonsoft.Json;

[assembly: LambdaSerializerAttribute(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]

namespace AWSLambdaBmi
{
    public class LambdaRequest
    {
        [JsonProperty(PropertyName = "body")]
        public string Body { get; set; }
    }

    public class LambdaResponse
    {
        [JsonProperty(PropertyName = "statusCode")]
        public HttpStatusCode StatusCode { get; set; }

        [JsonProperty(PropertyName = "headers")]
        public Dictionary<string, string> Headers { get; set; }

        [JsonProperty(PropertyName = "body")]
        public string Body { get; set; }
    }

    public class RequestParam
    {
        [JsonProperty(PropertyName = "hight")]
        public double Hight { get; set; }

        [JsonProperty(PropertyName = "weight")]
        public double Weight { get; set; }
    }

    public class ResponseParam
    {
        [JsonProperty(PropertyName = "bmi")]
        public double Bmi { get; set; }

        [JsonProperty(PropertyName = "ideal_body_weight")]
        public double IdealBodyWeight { get; set; }
    }


    public class Function
    {
        public LambdaResponse FunctionHandler(LambdaRequest input, ILambdaContext context)
        {
            var data = JsonConvert.DeserializeObject<RequestParam>(input.Body);

            // BMI = 体重kg / ( 身長(m) * (身長m) )
            var bmi = data.Weight / Math.Pow(data.Hight / 100, 2.0);

            // 適正体重 = 身長(m) * 身長(m) * 22
            var idealBodyWeight = Math.Pow(data.Hight / 100, 2.0) * 22;

            return new LambdaResponse
            {
                StatusCode = HttpStatusCode.OK,
                Headers = null,
                Body = JsonConvert.SerializeObject(
                    new ResponseParam
                    {
                        Bmi = bmi,
                        IdealBodyWeight = idealBodyWeight
                    })
            };
        }
    }
}

6. Lambdaの設定をする

作成したプログラムを AWS Lambda にアップロード前に設定を行います。 ほとんどの項目が自動的に入力されています。 Account ProfileRegionFunction Nameの3つを設定した後に次に進んで下さい。

Account Profileを間違って作成した場合など、情報を修正する場合はこちら VisualStudioで設定したAWSのプロファイルを修正する

また、IAM でグループやユーザーの作成を行っていない場合は、 任意のグループにAWSLambdaFullAccessポリシーをアタッチした後に、 任意のユーザーを作成して下さい。 ※適切な権限割当についてはご自身で判断願います。

f:id:kagasu:20200423035719p:plain f:id:kagasu:20200423035724p:plain

No 項目名 必須? 説明
1 Profile Name 必須 プロファイル名。
VisualStudio で表示される時の名前
2 AccessKey 必須 アクセスキーID。
IAMで作成してコピペする。
3 Secret Access Key 必須 シークレットアクセスキー。
IAMで作成してコピペする。
4 Account Number オプション アカウントID。空でOK。
5 Account Type 必須 アカウントタイプ。
基本は Standard AWS Account を選択する。

7. アップロードする

Role NameMemory(MB)Timeout(Secs)の3つを選択してUploadをクリックして下さい。

項目名 説明
Memory(MB) 最低の128MBで問題ありません。
次の節で紹介する Log をみて調整します。
Timeout(Secs) 10秒に設定します。
初回起動時のビルドに時間がかかるので長めに設定します。
次の節で紹介する Log をみて調整します。

また、 IAM でロールを作成していない場合は AWSLambdaFullAccessポリシーをアタッチしてロールを作成して下さい。 ※適切な権限割当についてはご自身で判断願います。 ※6 で設定したアカウントにロール作成権限もあれば、Role Nameコンボボックスから作成することも可能です。

f:id:kagasu:20200423035736p:plain

8. Lambdaでテストする

作成した Lambdaをテストして結果を確認します。

また、画面下部に表示されているLogには、 実行時に使用されたメモリや実行時間が出力されています。 この結果を見てメモリやタイムアウトの設定を調整させます。

{
  "body": "{\"height\": 168.0, \"weight\": 50.0}"
}

実行結果 f:id:kagasu:20200423035745p:plain

9. API Gatewayを追加する

AWS Lambda管理画面を開き、関数を選択した後にトリガーとしてAPI Gatewayを追加します。 ※リンクは東京リージョンになっているので、海外リージョンでLambda関数を作成した場合は各自合わせて下さい。 f:id:kagasu:20200423035755p:plain

10. HTTPでテストする

9 で作成したエンドポイントをテストします。 f:id:kagasu:20200423035802p:plain

Content-Typeapplication/jsonです。

{
  "hight" : 168.0,
  "weight" : 50.0
}

実行結果 f:id:kagasu:20200423035807p:plain

Ⅴ. 参考文献