😺

【AWS×Java】SAMで冷蔵庫管理アプリを構築 #1 API Gateway + Lambda編(Hello API)

に公開

はじめに

当記事の最終ゴールについては以下の記事をご確認ください。
https://zenn.dev/superrelax102/articles/424ebd380d6c53

今回のゴール:API Gateway + Lambda(Java)でHello APIをデプロイする
前提読者:AWS初心者、開発初心者

以下を実施することで従量課金が発生します。その点については自己責任でお願いします。

アーキテクチャ概要

今回は以下赤枠部分を完成させます。

図1: サーバレス構成の全体像

事前準備

開発環境は以下の通りです。
 -OS:Windows11
 -開発言語:Java21(2025年8月時点、最新)
 -開発エディタ:VScode

また、AWSについて以下が設定できている前提とします。
 -IAMユーザー作成されている
 -AWS CLI使用可
  ↓確認方法

  aws --version

-AWS SAM CLI使用可
  ↓確認方法

  sam --version

プロジェクトの初期化

ディレクトリ作成

デスクトップに以下のディレクトリを作成します。
FridgeApp2/
├── backend/ # API Gateway~DynamoDB関連のコード
├── frontend/ # S3に格納するhtml,css,JavaScriptのコード

Infrastructure Composerでプロジェクト作成

以下の手順でプロジェクトを作成します。

-FridgeApp2直下でひな形プロジェクト作成

sam init

このコマンドを実行すると以下のような質問が来るのでそれぞれ答えていきます。

回答内容
You can preselect a particular runtime or package type when using the `sam init` experience.
Call `sam init --help` to learn more.

Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1 #AWS Quick Start Templatesを選択

Choose an AWS Quick Start application template
        1 - Hello World Example
        2 - Data processing
        3 - Hello World Example with Powertools for AWS Lambda
        4 - Multi-step workflow
        5 - Scheduled task
        6 - Standalone function
        7 - Serverless API
        8 - Infrastructure event management
        9 - Lambda Response Streaming
        10 - GraphQLApi Hello World Example
        11 - Full Stack
        12 - Lambda EFS example
        13 - Serverless Connector Hello World Example
        14 - Multi-step workflow with Connectors
        15 - DynamoDB Example
        16 - Machine Learning
Template: 1 #Hello World Exampleを選択

Use the most popular runtime and package type? (python3.13 and zip) [y/N]: N
#Pythonをキャンセル

Which runtime would you like to use?
        1 - dotnet8
        2 - dotnet6
        3 - go (provided.al2)
        4 - go (provided.al2023)
        5 - graalvm.java11 (provided.al2)
        6 - graalvm.java17 (provided.al2)
        7 - java21
        8 - java17
        9 - java11
        10 - java8.al2
        11 - nodejs22.x
        12 - nodejs20.x
        13 - nodejs18.x
        14 - python3.9
        15 - python3.13
        16 - python3.12
        17 - python3.11
        18 - python3.10
        19 - ruby3.4
        20 - ruby3.3
        21 - ruby3.2
        22 - rust (provided.al2)
        23 - rust (provided.al2023)
Runtime: 7 #java21を選択

What package type would you like to use?
        1 - Zip
        2 - Image
Package type: 1 #今回はZipを使用。Imageはコンテナ(Docker)の使用が必要。

Which dependency manager would you like to use?
        1 - gradle
        2 - maven
Dependency manager: 2 #mavenを使用

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: N

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: N

Would you like to set Structured Logging in JSON format on your Lambda functions?  [y/N]: N

Project name [sam-app]: backend #ディレクトリ名をbackendにしている

今回はなるべくシンプルな構成ということで 1 - AWS Quick Start Templates を選択し、
最小構成である 1 - Hello World Example を選びました。
最初はAPI Gateway + LambdaだけでHello APIを動かし、次回以降DynamoDBやCognitoを追加していきます。また、デフォルトだとPythonになるのですが、私自身がJavaを学習中ですのでJavaを選択しております。

※1:Javaは大規模処理に向いている一方、コールドスタート※2により起動が遅くなるというデメリットもあるようです。(冷蔵庫アプリでも確かに動き始めが遅いです)

※2:Javaはコールドスタートが相対的に重めです。メモリ増量/依存縮小/SnapStartなどで後から改善できます。

Application Composerで構成図を確認

backendディレクトリの配下に「template.yaml」があるので右クリックをして
「Open with Infrastructure Composer」を選択してください。
すると以下のような図が表示されているかと思います。
(旧称がInfrastructure Composerらしく、私は「Infrastructure Composer」と表示されていましたが、「Application Composer」と表示されている方はそちらを選択してください)

-図2 Application Composer

HelloWorld Lambdaの中身を確認

以下のファイルを見るとリクエストを受けてレスポンスを返すだけのプログラムに
なっていることがわかります。

backend\HelloWorldFunction\src\main\java\helloworld\App.java
 try {
     final String pageContents = this.getPageContents("https://checkip.amazonaws.com");
     String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents);

     return response
             .withStatusCode(200)
             .withBody(output);
 } catch (IOException e) {
     return response
             .withBody("{}")
             .withStatusCode(500);
 }

ビルド&デプロイ

cd backend #template.yamlがあるbackendディレクトリに移動
sam build
sam deploy --guided

このコマンドを実行すると以下のような質問が来るのでそれぞれ答えていきます。

回答内容

Stack Name [backend]: FridgeApp2 #任意の名前
AWS Region [ap-northeast-1]: #東京リージョンにしたが他のリージョンも可
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [Y/n]: Y
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: Y
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [y/N]: N #失敗したときにロールバックさせる
HelloWorldFunction has no authentication. Is this okay? [y/N]: y # ※3参照
Save arguments to configuration file [Y/n]: Y
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
 ・
 ・
 ・
Deploy this changeset? [y/N]: y

※3 認証の設定ですが、公開APIとしているので誰でも実行できる状態でデプロイしています。
   そのため、エンドポイントURLを知っている人であれば誰でもアクセス可能です。
   本番運用や実際のサービス開発では、CognitoやIAM Authorizerなどを利用して
   必ず認証を導入してください
   (この記事の内容をそのまま本番に適用するのは自己責任となります)

認証については後日改めて記事を作成します。

動作確認

デプロイが成功していれば、ログの中に以下のような記載がでているかと思います。

Key                 HelloWorldApi
Description         API Gateway endpoint URL for Prod stage for Hello World function
Value               https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/

上記のValueの部分のURLをコピーし、以下を実行してください。

curl https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/

以下のような結果が返ってきたら成功です。

StatusCode        : 200
StatusDescription : OK
Content           : { "message": "hello world", "location": "XXX.XXX.XXX.XXX" }

今後の予定

今回作成したAPI Gateway + Lambdaの構成を応用して次回はDynamoDBへのアクセス部分を作成します!さらにCognitoで認証、最終的にCI/CDへ展開していく予定です!

Discussion