本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回のハッカーは一野瀬翔吾さんで、テーマは「AWS Lambda入門」( 2)です。
<前回(1)はこちら 。>
シンプルなHTTP APIの作成
無事にLambda関数の実行ができましたが、実行するにはマネジメントコンソールかAWS CLIが必要です。これでは気軽に利用できません。そこで、Lambda関数にHTTPエンドポイントを追加して、HTTP APIとして利用できるようにしましょう。
HTTPリクエストを待ち受ける
先ほどのSAMテンプレートに次の❶の設定を追加します。https://xxxxx.lambda-url.ap-northeast-1.on.aws/
のようなURLが発行されるので、マネジメントコンソールからURLを確認しておきましょう。
リスト template.yaml
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"
┐
FunctionUrlConfig: ┼-❶
AuthType: NONE ┘
HTTPレスポンスを返す
受け取ったHTTPリクエストを処理するには、仕様に沿った形式でLambda関数を実装する必要があります。実装を簡単に行えるよう、AWS::Lambda
モジュールにはPSGI(Perl Web Server Gateway Interface )をLambda関数に変換するユーティリティが実装してあります。PSGIはPerlで書かれたWebアプリケーションの呼び出し規約で、多くのPerl製Webフレームワークが対応しています。
例として、「 hello, world」と返すだけのPSGIアプリケーションをLambda関数に変換してみます。
リスト handler.pl
use v5.36 ;
use utf8;
use AWS::Lambda::PSGI;
my $app = sub {
return [
200 ,
['Content-Type' => 'text/plain' ],
["hello, world\n" ]
];
};
my $func = AWS::Lambda::PSGI->wrap($app);
sub handle ($payload , $context ) {
return $func->($payload);
}
1 ;
APIの動作確認
sam deploy
を使ってデプロイしましょう。AWSによって発行されたURLにアクセスすると、「 hello, world」という文字列が表示されます。
$ 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テンプレートに追記しましょう。
リスト template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
┐
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"
┐
- "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(Software Development Kit )が必要です。Perl 向けのSDKは公式には提供されていませんが、Paws という有志による実装があります。❷はPawsモジュールを読み込む設定です。
テーブルへの書き込み処理の実装
DynamoDBにカウンタの値を書き込むプログラムを実装します。カウンタの値の更新にはDynamoDBのAPIであるUpdateItemを利用します。APIの詳細は、DynamoDBのデベロッパーガイド を参照してください。
リスト handler.pl
use v5.36 ;
use utf8;
use AWS::Lambda::PSGI;
use Paws;
my $db = Paws->service(
'DynamoDB' ,
region => $ENV{AWS_DEFAULT_REGION}
);
my $app = sub {
my $ret = $db->UpdateItem(
TableName => $ENV{TABLE_NAME} ,
Key => { id => { S => "data" } },
UpdateExpression => 'ADD cnt :incr' ,
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だけではありません。興味を持った人はぜひいろいろと試してみてください。
さて、次回の執筆者は岡林大さんで、テーマは「コーディングを楽にするPerl Navigator 」です。お楽しみに。