LoginSignup
0
0

AWS Lambda + QuarkusでのREST API作成

Last updated at Posted at 2023-08-23

はじめに

QuarkusはコンテナファーストのJavaフレームワークですが、AWS Lambdaにも対応しています。当記事では、AWS Lambda上で、QuarkusベースのREST APIを作成・動作させる手順を説明します。

前提環境

当記事では以下を前提とします(ツールのバージョンは一致しなくても実施は可能)。

  • AWSアカウントを保有していること
  • Quarkus CLI 3.2.3 Final
  • Maven 3.8.7
  • AWS CLI 2.13.10

実施手順

基本的には、Quarkusのドキュメントをベースに進めていきます。

Mavenプロジェクトの作成

まず、Mavenでプロジェクトを作成します。

mvn archetype:generate \
       -DarchetypeGroupId=io.quarkus \
       -DarchetypeArtifactId=quarkus-amazon-lambda-archetype \
       -DarchetypeVersion=3.2.4.Final

上記のコマンドを実行後、groupIdなど、それぞれ以下の値を入力します。

  • groupId:org.example
  • artifactId:quarkus-lambda-example
  • version:<ブランク>
  • package:<ブランク>

以下が実行例です。

Define value for property 'groupId': org.example
Define value for property 'artifactId': quarkus-lambda-example
Define value for property 'version' 1.0-SNAPSHOT: : 
Define value for property 'package' org.example: : 
Confirm properties configuration:
groupId: org.example
artifactId: quarkus-lambda-example
version: 1.0-SNAPSHOT
package: org.example
Y: :

上記により、quarkus-lambda-exampleというディレクトリが作成されるので、そのディレクトリに移動します(以降はquarkus-lambda-exampleディレクトリで作業します)。

作成されたプロジェクトの構造は以下のようになっています。
2023-08-22 at 16.23.20@2x.png

作成されたpom.xmlファイルの中を見てみます。Quarkusではquarkus-amazon-lambdaエクステンションが提供されており、これがLambda独特の要素を吸収してくれます。

pom.xml
    <dependencies>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-amazon-lambda</artifactId>
        </dependency>
        <!-- 中略 -->
    </dependencies>

JavaでLambda関数を作成する際、ハンドラクラスを作成しますが、Quarkusのquarkus-amazon-lambdaエクステンションでは、1つのプロジェクト内に複数のハンドラクラスを用意し、application.propertiesによる設定、または環境変数によって、Lambda関数で実行されるハンドラクラスを切り替えることが可能になっています。

Mavenでのプロジェクト作成によるデフォルトで、application.propertiesではtestが指定されているので、@Named("test")が設定されているハンドラクラス(TestLambda.java)が実行されます。

application.properties
quarkus.lambda.handler=test

TestLambda.javaを見てみます。ここでは、ProcessingServiceクラスをインジェクトしており、実質的な処理はProcessingServiceクラスが担っています。

TestLambda.java
package org.example;

import jakarta.inject.Inject;
import jakarta.inject.Named;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

@Named("test")
public class TestLambda implements RequestHandler<InputObject, OutputObject> {

    @Inject
    ProcessingService service;

    @Override
    public OutputObject handleRequest(InputObject input, Context context) {
        return service.process(input).setRequestId(context.getAwsRequestId());
    }
}

ProcessingServiceクラスは以下のようになっています。Lambdaの入力で与えられたgreetingnameの値を文字列連結して返すという単純な内容です。

ProcessingService.java
package org.example;

import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class ProcessingService {

    public static final String CAN_ONLY_GREET_NICKNAMES = "Can only greet nicknames";

    public OutputObject process(InputObject input) {
        if (input.getName().equals("Stuart")) {
            throw new IllegalArgumentException(CAN_ONLY_GREET_NICKNAMES);
        }
        String result = input.getGreeting() + " " + input.getName();
        OutputObject out = new OutputObject();
        out.setResult(result);
        return out;
    }
}

ビルド

では次に、ソースコードをビルドし、デプロイパッケージを作成します。以下のコマンドを実行します。

quarkus build

これにより、targetディレクトリが作成され、以下のパッケージ群がビルドされます。特に赤枠で囲ったfunction.zipmanage.shが重要で、それぞれ以下の内容になっています。

  • function.zip:Lambdaにデプロイされるファイル
  • manage.sh:AWS CLIを使用し、Lambdaへのデプロイ処理を実行するスクリプト
    2023-08-22 at 18.04.47@2x.png

manage.shの中身を見ると、ファイルの中程に以下のような行があります。変数で、Lambda関数の名前、ハンドラー、ランタイムを指定しています。

FUNCTION_NAME=QuarkusLambdaExample
HANDLER=io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest
RUNTIME=java11

AWS CLIの設定

manage.shではAWS CLIを使用しますが、AWS CLIを使用するにあたり、事前の設定を実施します。まず、以下のコマンドを実行し、AWS CLIを使用できるようにします。

aws configure

上記のコマンドでは、AWSのIAMユーザのAccess Key、Secret Access Keyが聞かれます。これらは、AWSコンソールの「IAM」→「ユーザー」→自身のIAMユーザー→「セキュリティ認証情報」→「アクセスキーを作成」で作成しておきます(詳細な手順は割愛します)。

Lambda関数の実行ロール作成

次に、Lambda関数がAWSのリソースにアクセスできるようアクセス許可を付与するための実行ロールを作成します。詳細はAWSのドキュメントを参照ですが、以下に手順のみを記載します。

# `lambda-ex`という名前のロールを作成する。
aws iam create-role --role-name lambda-ex --assume-role-policy-document '{"Version": "2012-10-17","Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]}'

# 作成したロールに AWSLambdaBasicExecutionRole ポリシーを付与する
# これにより、Lambda関数がログをCloudWatch Logsに出力することが可能になる
aws iam attach-role-policy --role-name lambda-ex --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

作成したlambda-exロールのARNを取得します。下記のコマンドで出力されたJSONのRole.Arnの値をメモしておきます。

aws iam get-role --role-name lambda-ex

Lambda関数の作成

それではいよいよLambda関数を作成します。以下のコマンドを実行します。

LAMBDA_ROLE_ARN="<上記で取得したlambda-exロールのARN>" sh target/manage.sh create

コマンドが正常終了することを確認し、AWSコンソールのLambdaのページにアクセスすると、manage.shで関数名として指定されていた「QuarkusLambdaExample」が作成されています。
2023-08-22 at 18.27.34@2x.png

では次に、作成した関数をテストしてみます。上記の関数一覧の「QuarkusLambdaExample」をクリックし、「テスト」タブを選択します。「イベント名」に適当な名前を入力し、「イベントJSON」に以下の内容を入力し、「テスト」ボタンをクリックします。

{  
  "name": "Bill",  
  "greeting": "hello"  
}

2023-08-22 at 18.28.44@2x.png

テスト結果が以下の通り成功となり、レスポンスのJSONのresulthello Billが出力されていればOKです。
2023-08-22 at 18.37.54@2x.png

API Gatewayの作成 & 外部からのAPIアクセス

次に、Lambda関数をAPI化し、外部(インターネット)からアクセスできるようにします。具体的にはAPI Gatewayを作成します。AWSコンソールのAPI Gatewayのページにアクセスし、「APIを作成」ボタンをクリックします。
2023-08-22 at 18.43.29@2x.png

「REST API」の「構築」ボタンをクリックします。
2023-08-22 at 18.43.42@2x.png

「API名」に適当な名前を入力し、「APIの作成」ボタンをクリックします。
2023-08-22 at 18.44.07@2x.png

「アクション」→「メソッドの作成」を選択します。
2023-08-22 at 18.44.37@2x.png

「POST」メソッドを選択し、チェックマークをクリックします。
2023-08-22 at 18.45.19@2x.png

「統合タイプ」で「Lambda関数」を選択し、「Lambda関数」で先ほど作成したLambda関数「QuarkusLambdaExample」を選択し、「保存」ボタンをクリックします。
2023-08-22 at 18.45.31@2x.png

「テスト」をクリックします。
2023-08-22 at 18.46.45@2x.png

「リクエスト本文」に前述のJSONを入力し、「テスト」ボタンをクリックします。
2023-08-22 at 18.47.06@2x.png

「ステータス」で200が返り、「レスポンス本文」でLambda関数本体のテスト実施時と同様のレスポンスが出力されていればOKです。
2023-08-22 at 18.47.40@2x.png

「アクション」→「APIのデプロイ」を選択し、APIのデプロイを行います。
2023-08-22 at 18.48.33@2x.png

「デプロイされるステージ」で「新しいステージ」を選択し、「ステージ名」を「example」とし、「デプロイ」ボタンをクリックします。
2023-08-22 at 18.49.05@2x.png

すると、APIがデプロイされ、APIのエンドポイントが表示される(赤枠部分)のでメモします。
2023-08-22 at 18.49.48@2x.png

ここまででAPIがデプロイされ、外部からアクセスできるようになりました。最後にAPIの稼働確認を実施します。以下のcurlコマンドを実行します(URL部分は先ほどメモしたAPIのエンドポイントに置き換えてください)。以下のように、Lambda関数本体のテスト実施時と同様のレスポンスが出力されていればOKです。

curl -X POST -H "Content-Type: application/json" -d '{"name" : "Bill", "greeting" : "hello"}' https://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/example
{"result":"hello Bill","requestId":"5aadf1cb-9460-47d5-90b2-8f6845817a0a"}
0
0
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
0
0