BFT名古屋 TECH BLOG

日々の業務で得た知識を所属するエンジニアたちがアウトプットしていきます。

【AWS】初心者向け! APIGatewayと連携させるLambda作成&コードの書き方

こんにちは!
株式会社BFT名古屋支店、新米エンジニアのプリンとDUKEです。

APIの勉強のためにAWSAPI GatewayとLambdaを使ってランダムで今日の運勢を表示させるREST APIを作った経験から、前回の記事ではAPIGatewayの設定値について解説しました。
今回は、その続きとしてLambdaの作成方法とコードを書くときのポイントを解説していきます。
Lambdaとは

そもそもLambdaとは、サーバレスにコードを実行をできるAWSのサービスです。

プログラムを実行したいとき、例えばEC2を使用する場合はインスタンスを作成してWebサーバとして構築してネットワークの設定をして……というように実行環境の準備に時間と手間がかかります。
Lambdaはサーバレスという言葉通り、そうした実行環境の準備が必要ありません。Lambdaを作成したらすぐにコードを書いてプログラムを実行できるのがLambdaのメリットです。

Lambdaの作成

まずはLambdaの作成から行っていきます。

Lambdaのコンソールにアクセスして、関数の作成を選択します。


作成画面に遷移するので「一から作成」を選択します。
基本的な情報として任意の関数名を入力し、使用する言語、アーキテクチャを選択します。

Lambdaで使用できる言語は、Node.js、PythonJavaRubyC#、Go、PowerShellなどがありますが、今回はPythonを使用しました。

「デフォルトの実行ロールを変更」の部分は「基本的なLambdaアクセス権限で新しいロールを作成」を選択しました。

これを選択することで、CloudWatchというログ監視サービスへのアクセス権限を持ったロールを自動でLambdaに付与してくれます。
それによってエラーが起きたときなどにLambdaのログをCloudWatchで確認できるようになります。

詳細設定は今回は特に変更していません。
あとは「関数の作成」を押下して、Lambdaの作成は完了です!

Lambdaでコードを書く時のポイント:HTTPレスポンス

APIGatewayとLambdaを統合すると、Lambda関数がHTTPリクエストを処理し、HTTPレスポンスを生成することができます。
HTTPリクエストとはWebサーバとHTTPで通信する際に何を要求するか(単にWebページを表示してほしい、データを登録してほしいなど)を示すためのものです。
そして、HTTPレスポンスはその要求に対して何を返すかを示すためのものです。

HTTPリクエストに関する項目はAPIGateway側で設定します。
(※APIGatewayの設定については前回の記事をご覧ください)
Lambdaプロキシ統合を使用する場合にはLambda側のコードのLambdahandlerのreturn部分をHTTPレスポンスの形式で記述する必要があります。
HTTPレスポンスとは以下の3つの要素で構成されます。
ステータスコード
②ヘッダー
③ボディ

例えば今回作成したコードには以下のように記載しています。

return { 
   'statusCode': 200,
   'headers': {
      'Content-Type': 'text/plain; charset=utf-8'
   },
   'body': '\n'.join(result)
}

statusCodeはリクエストの結果を示す3桁の値で、200は「成功」を示します。
これは、クライアントからのリクエストが成功し、正常なレスポンスが返されたことを意味しています!
ほかの値に関しても一部紹介するので、参考にしてください!


204:リクエストは成功したが、レスポンスのbodyが存在しない
400:不正なリクエス
401:認証が必要なリクエストに対して、認証情報がない。もしくは無効
500:サーバ内エラー
503:サービスが一時的に利用できない



次にheadersです。これはレスポンスに関する情報を含むオブジェクトです。
headersに書いてあることの意味としては、HTTPレスポンスのコンテンツタイプがtext形式であり、文字エンコーディングUTF-8であることを示しています。
ちなみにUTF-8を指定しない場合、PCとAndroidでは正常に表示されますが、iPhoneの場合文字化けしてしまうので注意してください!

最後にbodyですが、ここには実際のレスポンスデータが含まれます。
Lambdaプロキシ統合を使用する場合は、このようにHTTPレスポンス形式でreturnを記述することで、bodyに設定した値をレスポンスデータとして返してくれます。
このコードではresult というリストを作成し、bodyに指定しているので「resultをレスポンスとして返す」という意味になります。(ちなみに '\n' と記述することで、リストを1要素ごとに改行して表示してくれます!)
このようにAPI-Gateway/Lambda関数間でリクエスト・レスポンスの変換やマッピングを1つ1つ設定する必要がなく、シンプルで迅速なAPI作成が可能になるのがLambdaプロキシ統合を使用するメリットです。

まとめると、このHTTPレスポンスは成功(ステータスコード: 200)を示し、text形式のデータを含みます。
そして、文字コードUTF-8に指定しています。
さらに、result リスト内のデータが改行で区切られた形でレスポンスする。という内容になります! このように記述することで、Lambda関数からのリクエストを処理し、クライアントに対してtext形式のデータを含む正常なレスポンスを返すことができます!

コード紹介

それでは最後に今回作成したコードを紹介します!

import random
#運勢名、★、お酒、ラッキーパーソンリスト定義
unseinames = ['金運', '仕事運', '対人運', '恋愛運']
stars = ['★☆☆☆☆', '★★☆☆☆', '★★★☆☆', '★★★★☆', '★★★★★']
osakes = ['ほろよい', 'ハイボール', 'Slat', 'スクリュードライバー', 'ストゼロ', '休肝日']
luckeypersons =  ['A', 'B', 'C']

#総合運を各運勢の平均から算出する関数
def sogoun(all_stars):
    #★の数で総合運を決定
    total_stars = sum(all_stars)
    if total_stars <= 6:
      return ' ★☆☆☆☆'
    elif total_stars <= 9:
      return ' ★★☆☆☆'
    elif total_stars <= 12:
      return ' ★★★☆☆'
    elif total_stars <= 16:
      return ' ★★★★☆'
    else:
      return ' ★★★★★'

#AWS Lambdaハンドラ関数
def lambda_handler(event, context):
    result = [] #結果格納用リスト
    all_stars = [] #各運勢の★のリスト
    X=0 #ループカウンタ
    
    #各運勢の★を取得
    result.append('💗:・*:.。 。.:*・゚今日のNB運勢・*:.。 。.:*・゚:💗')
    for _ in range(4):
        result.append('【' + unseinames[X] + '】')
        tmplucks = random.choice(stars)
        result.append('  ' + tmplucks)
        result.append('')
        tmplucks2 = tmplucks.count('★')
        all_stars.append(tmplucks2)
        X = X + 1
        
    result.append('【総合運】')
    result.append(sogoun(all_stars)) #総合運をresultリストに追加
    result.append('')
    result.append('【ラッキーアルコール】')
    result.append('  ' + random.choice(osakes)) #ランダムにosakesリストから取得
    result.append('')
    result.append('【ラッキーパーソン】…お話ししたりご飯に行くといいことがあるかも!?')
    result.append('  ' + random.choice(luckeypersons)) #ランダムにluckeypersonsリストから取得
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'text/plain; charset=utf-8'
        },
        'body': '\n'.join(result)
    }

このコードをLambdaに記述し、デプロイしてURLにアクセスするとこんな画面になるかと思います!

デプロイ方法は前回の記事をご覧ください。


Lambdaの作成方法とコードの書き方は以上です。
ここまで読んでいただき、ありがとうございました。