本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回のハッカーは一野瀬翔吾さんで、テーマは
<前回
シンプルなHTTP APIの作成
無事にLambda関数の実行ができましたが、実行するにはマネジメントコンソールかAWS CLIが必要です。これでは気軽に利用できません。そこで、Lambda関数にHTTPエンドポイントを追加して、HTTP APIとして利用できるようにしましょう。
HTTPリクエストを待ち受ける
先ほどのSAMテンプレートに次の❶の設定を追加します。https://
のようなURLが発行されるので、マネジメントコンソールからURLを確認しておきましょう。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
Function:
Type: AWS::Serverless::Function
Properties:
CodeUri: src
Handler: handler.handle
Runtime: provided.al2
Layers:
- "arn:aws:lambda:ap-northeast-1:445285296882\
:layer:perl-5-36-runtime-al2-x86_64:1"
# Function URLsを有効化する ┐
FunctionUrlConfig: ┼-❶
AuthType: NONE ┘
HTTPレスポンスを返す
受け取ったHTTPリクエストを処理するには、仕様に沿った形式でLambda関数を実装する必要があります。実装を簡単に行えるよう、AWS::Lambda
モジュールにはPSGI
例として、
use v5.36;
use utf8;
use AWS::Lambda::PSGI;
# "hello, world"と返すだけのPSGIアプリケーション
my $app = sub {
return [
200,
['Content-Type' => 'text/plain'],
["hello, world\n"]
];
};
# PSGIをAWS Lambda Function URLsに対応した関数に変換
my $func = AWS::Lambda::PSGI->wrap($app);
# アプリケーションを実行
sub handle ($payload, $context) {
return $func->($payload);
}
1;
APIの動作確認
sam deploy
を使ってデプロイしましょう。AWSによって発行されたURLにアクセスすると、
$ sam deploy $ curl https://xxxxx.lambda-url.ap-northeast-1.on.aws/ hello, world
ほかのAWSサービスとの連携
最後にAWSサービスとの連携を試してみましょう。連携するサービスにはDynamoDBを使用し、APIへのアクセス数をカウントするカウンタを作ってみます。
DynamoDBのテーブルの作成
DynamoDBはAWSが提供するkey-value形式のデータベースです。リレーショナルデータベースのような複雑な集計処理はできませんが、単純なデータの保存なら手軽に扱えます。DynamoDBを扱うための設定をSAMテンプレートに追記しましょう。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
# DynamoDBのテーブルを作成 ┐
Table: ┼ー❶
Type: AWS::Serverless::SimpleTable ┘
Function:
Type: AWS::Serverless::Function
Properties:
CodeUri: src
Handler: handler.handle
Runtime: provided.al2
Layers:
- "arn:aws:lambda:ap-northeast-1:445285296882\
:layer:perl-5-36-runtime-al2-x86_64:1"
# コンパイル済みのAWS SDK for Perlを読み込み ┐
- "arn:aws:lambda:ap-northeast-1:445285296882\ ┼-❷
layer:perl-5-36-paws-al2-x86_64:1" ┘
FunctionUrlConfig:
AuthType: NONE
# 書き込み先のテーブル名を、 ┐
# 環境変数経由でプログラムに渡す |
Environment: ├-❸
Variables: |
TABLE_NAME: !Ref Table ┘
# テーブルへの読み書き権限を付与 ┐
Policies: ├-❹
- DynamoDBCrudPolicy: |
TableName: !Ref Table ┘
❶でカウンタの数値を書き込むためのDynamoDBのテーブルを作成します。作成したテーブルの名前を❸でPerlのプログラムに渡します。❹はテーブルの読み書きの権限をLambda関数に付与するための設定です。
DynamoDBの読み書きを行うにはAWS SDK
テーブルへの書き込み処理の実装
DynamoDBにカウンタの値を書き込むプログラムを実装します。カウンタの値の更新にはDynamoDBのAPIであるUpdateItemを利用します。APIの詳細は、DynamoDBのデベロッパーガイドを参照してください。
use v5.36;
use utf8;
use AWS::Lambda::PSGI;
use Paws;
# DynamoDBに接続するためのクライアントを作成
my $db = Paws->service(
'DynamoDB',
region => $ENV{AWS_DEFAULT_REGION}
);
my $app = sub {
# カウンタをインクリメント
my $ret = $db->UpdateItem(
# DynamoDBのテーブル名
TableName => $ENV{TABLE_NAME},
# プライマリキーの指定
Key => { id => { S => "data" } },
# インクリメント命令を実行
# :incrの部分はプレースホルダー
UpdateExpression => 'ADD cnt :incr',
# プレースホルダ :incrに1を設定
ExpressionAttributeValues => {
':incr' => { N => '1' }
},
# 戻り値に更新後の値を返すよう設定
ReturnValues => 'UPDATED_NEW',
);
# 結果を返す
my $cnt = $ret->Attributes->Map->{cnt}->N;
return [
200,
['Content-Type' => 'text/plain'],
["$cnt\n"]
];
};
my $func = AWS::Lambda::PSGI->wrap($app);
sub handle ($payload, $context) {
return $func->($payload);
}
1;
APIの動作確認
sam deploy
を使ってデプロイしましょう。APIを呼び出すたびに数値が増えていくことが確認できます。
$ sam deploy $ curl https://xxxxx.lambda-url.ap-northeast-1.on.aws/ 1 $ curl https://xxxxx.lambda-url.ap-northeast-1.on.aws/ 2
まとめ
AWS Lambda入門ということで、Perlを使ってアクセスカウンタを作ってみました。本稿では一例としてHTTP APIを取り上げましたが、AWS Lambdaの利用はHTTP APIだけではありません。興味を持った人はぜひいろいろと試してみてください。
さて、次回の執筆者は岡林大さんで、テーマは