LoginSignup

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 1 year has passed since last update.

c#でAWSLambda関数を作ってみた

Posted at

C#でAWSLambda関数を作ってみた

この記事はOUCC Advent Calendar 2022の23日目の記事です。前回の記事は紅茶さんの「お気に入りの量産型・地雷系ファッションブランドについて語る」でした。

どうもこんにちは、3回のかきのたねです。
今知り合いとの忘年会を終えて酔いを冷ましながらこの記事を書いています。
エンジニアは孤独な職業と言いますが、最近人と遊んだり飲んだりするのが楽しくて仕方なくていよいよエンジニア失格かもしれませんね。。。
まあ、人付き合いも1種の立派な勉強と開き直っています。

さて先日AWSLambdaを触る機会があったので、備忘録として記事にしておこうと思います。

まずは準備

  • AWS Toolkit for Visual Studioのインストール
  1. VisualStudio 2022 を開く。
  2. 上のメニューから拡張機能拡張機能を管理するを選択
  3. AWS Toolkit for Visual Studioを選択してダウンロード。
  4. VisualStudioをいったん閉じるとインストールが開始される。
  • AWSでアカウント登録を済ませておきましょう。

プロジェクト作成

  1. VisualStudio2022を起動し新しいプロジェクトの作成画面を開くと、AWSLambdaプロジェクトのテンプレートが出てくるので、AWS Lambda Project (.Net Core -C#)を選択。
    初期設定1.png

  2. 以下の画面が出てくるので空のプロジェクトを選択。
    初期設定2.png

  3. 以下の構成でプロジェクトが作成されるはず。

    .Project
     |---- Properties
     |   └ launchSettings.json
     |--- Function.cs
     |--- aws-lambda-tools-defaults.json
     --- readme.md
    

AWSアカウントとの連携

  1. AWSのコンソールを開き、アカウント -> セキュリティ認証情報を選択。

  2. セキュリティ認証情報画面で、新しいアクセスキーの作成を選択してアクセスキーを作成。キーファイルのダウンロードを選択してアクセスキーをダウンロードする。(このファイルは無くさないように大切に保管しておく。)
    初期設定4.png

  3. VisualStudioで表示 -> AWSExplorerを選択してウインドウを開き、アカウント追加ボタン(赤線部分)をクリックする。
    初期設定5.png

  4. アカウント作成画面が出るので、ダウンロードしたキーファイルの情報を入力。
    プロフィール名は自由で、リージョンは一応東京を選択しておく。
    初期設定6.png

  5. OKを押して、正しく認証されれば以下のような画面になる。
    初期設定7.png

サンプル関数をAWSLambdaに発行、テストする

  • 入力文字列を受け取り、簡単なメッセージを返す以下のようなメソッドをLambdaに発行する。

        // -------------------------------------------------------------------------------
        #region +LambdaTestFunc:AWS用の簡単な関数
        // -------------------------------------------------------------------------------
        /// <summary>
        /// AWSLambdaで実行されるテスト用の関数です。
        /// ただ入力を受け取って簡単な文字列を返します。
        /// </summary>
        /// <param name="input">入力</param>
        /// <param name="context">関数とリクエストに関する情報を持つ[コンテキストオブジェクト](</param>
        /// <returns>返答メッセージ</returns>
       [LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
        public string LambdaTestFunc(string input, ILambdaContext context)
        {
            return $"こんにちは: {input}さん";
        }
        #endregion (LambdaTestFunc)
    
    1. ソリューションエクスプローラーでプロジェクトを右クリック, Publish to AWS Lambda...をクリック。

    2. 以下のように入力を行う。FunctionNameDescriptionにはそれぞれLambda関数名と簡単な説明を入力する。
      発行1.png

    3. Lambda関数に与える権限とタイムアウト時間、メモリを設定する。

      • 権限にはBasicExecutionRoleを設定した。ReadOnlyと違って,Console.WriteLineがメソッドでログをCloudWatchに出力できるようになるためである。
        発行2.png

VisualStudioでのテスト

  • VisualStudio上でFunctionウィンドウからLambda上の関数を呼び出すことができる。
    左側のテキストボックスが入力で、Invokeボタンで呼び出す。返答は右に表示される。
    発行3.png

AWSでのテスト

  • AWSコンソール上でもLambdaでテストしたい関数を開くことでテストができる。
    発行4.png

LambdaをAPIGateway経由で呼び出そう

  • 今度は発行したLambda関数をAPIとして呼び出せるようにします
  1. NugetからNewtonsoft.JsonAmazon.Lambda.Serialization.Jsonを取得。

  2. Lambda関数の戻り値をAPIGatewayに対応させるため、新しいクラスを作成する。
    実際にはLambda関数はこのクラスを戻り値といて返しますが、Jsonに変換されてAPIGatewayに渡されます。

    • HttpStatusCodeIsBase64Encoded, HeadersプロパティはAPIGatewayが参照する情報で、ユーザに渡したい値はBodyに文字列として渡します。クラスの情報を渡したい時はJson文字列にシリアライズして渡します。
    • JsonProperty属性はJsonに変換される際のキー名です。(指定しなかった場合プロパティ名がキーとなります。)
      APIGatewayに合わせてキー名がキャメルケースになるようにしています
    // ===================================================================================
    #region LambdaResponse:Lambda関数の返答クラス
    // ===================================================================================
    /// <summary>
    /// Lambda関数が戻り値として使用するクラスです。
    /// 実際にはJsonにシリアライズされて返されます。
    /// </summary>
    public class LambdaResponse
    {
        // ===============================================================================
        #region プロパティ
        // ===============================================================================
        /// <summary>Base64エンコードが行われているか</summary>
        [JsonProperty(PropertyName = "isBase64Encoded")]
        public bool IsBase64Encoded;
    
        /// <summary>HTTPのステータスコード</summary>
        [JsonProperty(PropertyName = "statusCode")]
        public HttpStatusCode StatusCode;
        /// <summary>HTTPのヘッダ情報</summary>
        [JsonProperty(PropertyName = "headers")]
        public Dictionary<string, string> Headers;
        /// <summary>本体メッセージ</summary>
        [JsonProperty(PropertyName = "body")]
        public string Body;
        #endregion (プロパティ)
    }
    #endregion (LambdaResponseクラス)
    
  3. APIGatewayに対応した新しいメソッドをLambdaに発行する。

        // -------------------------------------------------------------------------------
        #region +APIGatewayGetTest:APIGatewayのGETメソッドテスト用の簡単な関数
        // -------------------------------------------------------------------------------
        /// <summary>
        /// APIGatewayのGETメソッドをテストするメソッドです。
        /// Lambdaに登録されAPIGatewayのGETメソッドを通して呼び出されます。
        /// </summary>
        /// <param name="input">入力</param>
        /// <param name="context">関数とリクエストに関する情報を持つ[コンテキストオブジェクト]</param>
        /// <returns></returns>
        public LambdaResponse APIGatewayGetTest(object input, ILambdaContext context)
        {
            return new LambdaResponse() {
                IsBase64Encoded = false,
                StatusCode = HttpStatusCode.OK,
                Headers = new Dictionary<string, string>()
                    {
                        {"my_header", "my_value" }
                    },
                Body = $"こんにちは!!",
            };
        }
        #endregion (APIGatewayGetTest)
    
    • 発行したLambdaメソッドを呼び出したときの戻り値は以下のようにJsonになっています。

      {
          "isBase64Encoded" : false,
          "statusCode"      : 200,
          "headers"         : {
              "my_header" : "my_value"
          },
          "body"            : "こんにちは!!"
      }
      
    • 注意点: 引数を取らないとき変数inputの型は必ずobject型にしてください。RESTAPIから呼び出したときに以下のエラーが出ます。
      restApi5.png

  4. AWSコンソールからAPIGatewayを開き、APIの作成を選択。

    APIのタイプにREST APIを選択。
    restApi1.png

  5. 設定画面は以下のように選択する。プロトコルでWebSocketを選択すると、WebSocketによりコネクションを作って通信するAPIとなるが、今回はRESTでいい。
    restApi2.png

  6. アクション -> メソッドの作成を選択。
    restApi3.png

  7. 今回はGETメソッドを選択。

  8. Lambdaに発行した関数をAPIから呼び出すように登録する。
    restApi4.png

  9. 作成したRESTAPIを呼び出すと、以下のようになる。
    レスポンスの本文はBodyプロパティの文字列になっているのがわかる。
    restApi6.png

REST APIをデプロイ

  1. AWSコンソールのAPIの画面に戻り、アクション -> APIのデプロイを選択。
    restApi8.png

  2. デプロイされるステージに新しいステージを選択。ステージ名はURLにおけるパスになる。
    restApi9.png

  3. 以下のような設定画面が出るが、とりあえずデフォルトのままにして設定の保存を選択。
    restApi10.png

  4. AWSLambdaの画面に戻ると、APIGatewayがLambda関数に登録されているのがわかる。
    restApi7.png

    ここをクリックすると、エンドポイントのURLが表示される。
    (念のため隠しておきます)
    restApi11.png

    このURLからAPIGatewayを通じてLambda関数を呼び出すことができる。
    restApi12.png

最後に

このRESTAPIに引数を渡したり、パスワード認証をかけたりといった事もできるんですが、長くなるのでこのあたりまでにしておきます。

サーバレスというのはなにか魅力を感じますね。
あとけちなAWS君にしては5万リクエストまで無料というのもメリットの一つです。
何かに活かせないかな。。。アイデア募集中です。

0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up