みなさん、こんにちは。イノベーションLABのハヤシです。
今回は、以下の構成の Web アプリをさくっと作る手順をご紹介します。
バックエンド:Node.js の REST API(Amazon API Gateway / AWS Lambda)
フロントエンド:TypeScript の React
今回は全 3 回のうちの 1 回です。
必要な部分だけでも、ぜひ参考にしてみてください。
環境構築手順はこちらで紹介しています
blog.css-net.co.jp
1. 前提条件
1-1. 想定読者
「さくっとログイン機能を実装した Web アプリが作りたい」
「せっかくなら SPA + REST API でやりたい」
「AWS SAM や Amplify ライブラリを使ってみたい」
といった方々を想定しています。
必要最低限の方法のみ解説しているので、ほぼサンプルコードのままです。
その後のカスタマイズには、 Node.js や TypeScript / React の知識が必要になります。
とはいえ、この記事は知識があることを前提としていませんので、手順通りに実施していく分にはそれらの知識は不要です。
雰囲気をつかむために、まずはチャレンジしてみるのもおすすめです!
1-2. 作成するもの
Part 3 までで、以下の内容を実装します。
- DynamoDB を利してデータを登録/取得する API(Part1 / 2 / 3)
- サインイン画面(Part3)
- サインイン後にAPIからデータを取得して表示する画面(Part2 / 3)
1-3. 前提条件
OS - Windows 10 Pro (Home でも問題ありません)
VSCode - 1.69.1
Git - 2.37.1.windows.1
AWS CLI - 2.7.14
SAM CLI - 1.53.0
Node.js - 16.16.0
aws configure で認証設定がすんでいること
以下コマンドで、「Account」が自分が操作可能な Account ID になっていることを確認する
aws sts get-caller-identity # Profile を指定している場合は今後のコマンドも全て Profile を指定してください # aws sts get-caller-identity --profile <Profile名>
この後の手順は特に指示がない限り、エディタは VSCode でターミナルは Git Bash での操作となります
環境構築手順はこちらで紹介しています
blog.css-net.co.jp
2. 事前準備
2-1. 作業ディレクトリ作成
エクスプローラで作業用のディレクトリを作成しておきましょう。
私は「C:\work\tutorial-app」というディレクトリを作成して、 VSCode で開きました。
この状態からスタートです。
2-2. リポジトリ作成
まずは フロントエンド、バックエンドともにソースコードを管理する Git リポジトリを作成します。
GitHub でも良いのですが、今回は CodeCommit に作成します。
マネジメントコンソールから手動で作っても良いですが、CloudFormation で作ってみましょう。
VSCode のターミナルで作業します。
作業用ディレクトリに「templates」ディレクトリを作成し、以下の内容で「01_repo_template.yaml」というファイルを作成します。
templates/01_repo_template.yaml
AWSTemplateFormatVersion: "2010-09-09" Description: CodeCommit Repository Parameters: BackendRepoName: Type: String Default: "tutorial-app-back" FrontendRepoName: Type: String Default: "tutorial-app-front" Resources: BackendRepository: Type: AWS::CodeCommit::Repository Properties: RepositoryName: !Ref BackendRepoName FrontendRepository: Type: AWS::CodeCommit::Repository Properties: RepositoryName: !Ref FrontendRepoName Outputs: BackendHttpsUrl: Description: The URL to use for cloning the repository over HTTPS. Value: !GetAtt BackendRepository.CloneUrlHttp Export: Name: !Sub "${AWS::StackName}-Backend-HttpsUrl" BackendSshUrl: Description: The URL to use for cloning the repository over SSH. Value: !GetAtt BackendRepository.CloneUrlSsh Export: Name: !Sub "${AWS::StackName}-Backend-SSHUrl" FrontendHttpsUrl: Description: The URL to use for cloning the repository over HTTPS. Value: !GetAtt FrontendRepository.CloneUrlHttp Export: Name: !Sub "${AWS::StackName}-Frontend-HttpsUrl" FrontendSshUrl: Description: The URL to use for cloning the repository over SSH. Value: !GetAtt FrontendRepository.CloneUrlSsh Export: Name: !Sub "${AWS::StackName}-Frontend-SSHUrl"
バックエンド用に「tutorial-app-back」、フロントエンド用に「tutorial-app-front」という名前でリポジトリを作成するテンプレートです。
templates ディレクトリに移動して、デプロイコマンドを実行します。
cd templates
TEMPLATE_NAME="01_repo_template.yaml" REPO_STACK_NAME="tutorial-app-repo-stack" BACKEND_REPO_NAME="tutorial-app-back" FRONTEND_REPO_NAME="tutorial-app-front" aws cloudformation deploy --template ./${TEMPLATE_NAME} \ --stack-name ${REPO_STACK_NAME} \ --parameter-overrides \ BackendRepoName=${BACKEND_REPO_NAME} \ FrontendRepoName=${FRONTEND_REPO_NAME}
マネジメントコンソールで作業します。
以下のものができあがっていることを確認しましょう。
◆CloudFormation -> スタック
「tutorial-app-repo-stack」という名前の Stack
◆CodeCommit -> ソース -> リポジトリ
tutorial-app-back」「tutorial-app-front」という名前のリポジトリ
今後の設定のために、リポジトリの HTTPS パスを取得します。
◆CodeCommit -> ソース -> リポジトリ -> <対象リポジトリ名> -> URLのクローン -> HTTPSのクローン
※ back / front それぞれコピーして、メモしておきましょう
または、 CloudFormation からも確認できます。
◆CloudFormation -> スタック -> tutorial-app-repo-stack -> 出力
BackendHttpsUrl / FrontendHttpsUrl の値が HTTPS パスです。
2-3. ターミナルで git 設定
ターミナルで git 用の設定をしておきましょう。
以下を参考に進めていきます。
docs.aws.amazon.com
VSCode のターミナルで作業します。
以下のコマンドを実行して、 CodeCommit への認証に AWS の認証情報を使用する設定をします。
git config --global credential.helper '!aws codecommit credential-helper $@' # aws configure で profile 指定をしている場合はこちら # git config --global credential.helper '!aws codecommit credential-helper --profile <Profile名> $@' git config --global credential.UseHttpPath true
※複数の AWS アカウントを利用する可能性がある場合は以下を指定してリポジトリごとの設定にしておきます。
git config --global credential.<HTTPSパス>.helper '!aws codecommit credential-helper $@' # aws configure で profile 指定をしている場合はこちら # git config --global credential.<HTTPSパス>.helper '!aws codecommit credential-helper --profile <Profile名> $@' git config --global credential.<HTTPSパス>.UseHttpPath true
以下のコマンドで、 git を利用する際のユーザ情報をセットしておきます。
USER_NAME="<ユーザ名(Taro Hayashi など)>" USER_MAIL="<メールアドレス>" git config --global user.name "${USER_NAME}" git config --global user.email ${USER_MAIL}
参考
AWS CodeCommit リポジトリを作成する - AWS CodeCommit
AWS::CodeCommit::Repository - AWS CloudFormation
AWS CloudFormation で CodeCommit リソースを作成する - AWS CodeCommit
変換を伴うテンプレートの迅速なデプロイ - AWS CloudFormation
3. バックエンド API
3-1. API 作成
VSCode のターミナルで作業します。
作業用ディレクトリ(C:\work\tutorial-app)にいる前提で進めていきます。
ターミナルで以下コマンド(現在位置を出力)を打って、「/c/work/tutorial-app」であることを確認してください。
pwd
※「/c/work/tutorial-app/templates」にいる場合は「cd ../」で1階層上に戻ってください。
以下のコマンドで、 SAM のテンプレートに従ってプロジェクトを作成していきます
sam init
選択肢は以下のものを選んでみましょう。
- Which template source would you like to use?
- 1 - AWS Quick Start Templates
- Choose an AWS Quick Start application template
- 3 - Serverless API
- Which runtime would you like to use?
- 3 - nodejs16.x
- Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]:
- n
- ※ X-Ray は Lambda の監視をするための設定ですが、今回は設定しないようにします。
- Project name [sam-app]:
- tutorial-app-back
以下のような結果になります。
$ 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 Choose an AWS Quick Start application template 1 - Hello World Example 2 - Multi-step workflow 3 - Serverless API 4 - Scheduled task 5 - Standalone function 6 - Data processing 7 - Infrastructure event management 8 - Machine Learning Template: 3 Which runtime would you like to use? 1 - dotnet6 2 - dotnetcore3.1 3 - nodejs16.x 4 - nodejs14.x 5 - nodejs12.x 6 - python3.9 7 - python3.8 Runtime: 3 Based on your selections, the only Package type available is Zip. We will proceed to selecting the Package type as Zip. Based on your selections, the only dependency manager available is npm. We will proceed copying the template using npm. Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: n Project name [sam-app]: tutorial-app-back Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment) ----------------------- Generating application: ----------------------- Name: tutorial-app-back Runtime: nodejs16.x Architectures: x86_64 Dependency Manager: npm Application Template: quick-start-web Output Directory: . Next steps can be found in the README file at ./tutorial-app-back/README.md Commands you can use next ========================= [*] Create pipeline: cd tutorial-app-back && sam pipeline init --bootstrap [*] Validate SAM template: sam validate [*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch
最新の SAM では以下のエラーが出る方がいらっしゃるかと思います。
これは Windows のロングパス設定によるもので、 SAM init を実行するにはこれを ON にする必要があります。
上記エラーが発生した場合は↓の手順を実施してみてください
◆---------- SAM init エラー対応(クリックで開く) ----------◆
PowerShell を管理者モードで開きます。 VSCode からであれば、ターミナルの「+」マークの右横をクリックし、「PowerShell」を開きます。
以下のコマンドを打つと、 PowerShell が管理者モードで別ウィンドウで開きます。
Start-Process PowerShell.exe -Verb runas
管理者モードの PowerShell で以下のコマンドを実行すると、 Windows のロングパスの設定を ON にすることができます。
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" ` >> -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
※レジストリエディタで「HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem」の「LongPathsEnabled」を 1 にしても OK です
参考
Maximum Path Length Limitation - Win32 apps | Microsoft Learn
この設定が終わったら、あらためて「SAM init」を実行してみてください。
◆---------- SAM init エラー対応 ここまで ----------◆
3-2. API デプロイ
VSCode のターミナルで作業します。
無事にコマンドが終了すると、プロジェクトのディレクトリが作成されます。
以下のコマンドで、ビルドとデプロイをしてみましょう。
# /c/work/tutorial-app/ で実行 cd tutorial-app-back # ビルド sam build
ここで、Lambda 用のライブラリのインストールやパッケージ化が行われるので、少し時間がかかります。
ビルドが終わったら、いよいよデプロイしましょう。
# デプロイ sam deploy --guided
選択肢は以下のものを選んでみましょう。
- Stack Name [sam-app]:
- tutorial-app-back-stack
- ※CloudFormation で作成されるスタック名です
- AWS Region [ap-northeast-1]:
- そのまま Enter
- ※デプロイするリージョンです。そのまま「ap-northeast-1(東京)」で良いので Enter です
- Confirm changes before deploy [y/N]:
- n
- ※deploy 前に変更を確認するアクションを入れるかどうかです。ひとまず No としておきます
- Allow SAM CLI IAM role creation [Y/n]:
- y
- ※IAM Role を作成することを許可するかどうかです。作成したいので Yes です
- Disable rollback [y/N]:
- n
- ※ロールバックを許可しない設定です。失敗したらロールバックさせたいので No にします
- getAllItemsFunction may not have authorization defined, Is this okay? [y/N]:
- y
- ※ここから 3 つは、それぞれの API に認証がついていないが良いか?というものです。後でつけるので、今は Yes にしておきます
- getByIdFunction may not have authorization defined, Is this okay? [y/N]:
- y
- putItemFunction may not have authorization defined, Is this okay? [y/N]:
- y
- Save arguments to configuration file [Y/n]:
- y
- ※今回の設定を設定ファイルに保存するかどうか。保存するので Yes です
- SAM configuration file [samconfig.toml]:
- そのまま Enter
- ※設定ファイルの名前です。デフォルトの「samconfig.toml」でよいのでそのまま Enter です
- SAM configuration environment [default]:
- dev
- ※今回のデプロイ設定の環境名です。default のままでもよいですが、ここは「dev」としておきます
以下のような結果になるはずです。
$ sam deploy --guided Configuring SAM deploy ====================== Looking for config file [samconfig.toml] : Not found Setting default arguments for 'sam deploy' ========================================= Stack Name [sam-app]: tutorial-app-back-stack 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]: n #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 getAllItemsFunction may not have authorization defined, Is this okay? [y/N]: y getByIdFunction may not have authorization defined, Is this okay? [y/N]: y putItemFunction may not have authorization defined, Is this okay? [y/N]: y Save arguments to configuration file [Y/n]: y SAM configuration file [samconfig.toml]: SAM configuration environment [default]: dev ########## 中略 ########## Successfully created/updated stack - tutorial-app-back-stack in ap-northeast-1
マネジメントコンソールで作業します。
以下のものができあがっていることを確認しましょう。
◆CloudFormation -> スタック
「tutorial-app-back-stack」という名前の Stack
◆DynamoDB -> テーブル
「tutorial-app-back-stack-SampleTable-<ランダム文字列>」という名前のテーブル
◆API Gateway -> API
「tutorial-app-back-stack」という名前の API
◆Lambda -> アプリケーション
「tutorial-app-back-stack」という名前のアプリケーション
◆Lambda -> 関数
「tutorial-app-back-stack-getAllItemsFunction-<ランダム文字列>」
「tutorial-app-back-stack-getByIdFunction-<ランダム文字列>」
「tutorial-app-back-stack-putItemFunction-<ランダム文字列>」
という名前の関数
◆IAM -> Role
「tutorial-app-back-stack-getAllItemsFunctionRole-<ランダム文字列>」
「tutorial-app-back-stack-getByIdFunctionRole-<ランダム文字列>」
「tutorial-app-back-stack-putItemFunctionRole-<ランダム文字列>」
という名前のロール
このアカウント・リージョンで初めてデプロイする場合は、デプロイ用の S3 バケットも作成されているはずです。
このバケットに、デプロイに必要なものがアップロードされます。
◆CloudFormation -> スタック
「aws-sam-cli-managed-default」という名前の Stack
◆S3 -> バケット
「aws-sam-cli-managed-default-samclisourcebucket-<ランダム文字列>」という名前のバケット
3-3. API 動作確認
デプロイした API の動作確認をしてみましょう。
マネジメントコンソールで作業します。
◆API Gateway -> API -> tutorial-app-back-stack
GET -> テスト をクリックします。
「テスト」ボタンをクリックすると、「tutorial-app-back-stack-getAllItemsFunction-<ランダム文字列>」関数が実行されて、結果が取得されます。
※まだ DynamoDB にデータが入っていないので、空([])です
今度は POST -> テスト をクリックします
リクエスト本文に以下を入力し「テスト」ボタンをクリックすると、「tutorial-app-back-stack-putItemFunction-<ランダム文字列>」関数が実行されて、結果が取得されます。
※リクエスト本文
{ "id": "id1", "name": "name1" }
DynamoDB にもデータが登録されているかどうか確認しましょう。
◆DynamoDB -> テーブル -> tutorial-app-back-stack-SampleTable-<ランダム文字列>
テーブルアイテムの検索 をクリックします。
データが登録されていることが確認できます。
もう一度 GET でテストをして、今度はデータが返ってくることを確認します。
※Postman などを利用してデータの登録 / 確認をすることもできます
www.postman.com
API を利用してデータが登録/取得できることを確認できました。
3-4. リポジトリに登録
ここまでのデータを最初に作成したリポジトリに Push しておきましょう。
VSCode のターミナルで作業します。
バックエンド用ディレクトリ(C:\work\tutorial-app\tutorial-app-back)にいる前提で進めていきます。
以下のコマンドを実行して git リポジトリとして初期化します。
# /c/work/tutorial-app/tutorial-app-back/ で実行
git init
SAM で作成したファイルのうち、 git 管理から外したいファイルを「.gitignore」ファイルに追記します。
以下のコマンドを実行してください。
echo .aws-sam/ >> .gitignore echo samconfig.toml >> .gitignore
以下のコマンドで、管理対象ファイルを確認します。
git status
.aws-sam/ と samconfig.toml が入っていないことを確認して、以下コマンドで全てを Add / Commit します
git add . git commit -m "first commit"
以下のコマンドで、ローカルリポジトリとリモートリポジトリを紐づけます
git remote add origin https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/tutorial-app-back
※「https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/tutorial-app-back」の部分は、 リポジトリ作成時に確認した back 用のリポジトリの HTTPS パスを指定してください
長らく git のメインブランチは master でしたが、今後は main という名前を主流とすることになっています。
参考
The default branch for newly-created repositories is now main | GitHub Changelog
デフォルトだとブランチが「master」になっていますので、以下のコマンドで「main」に変えておきましょう。
git branch -m main
以下のコマンドで、リモートリポジトリに Push します。
git push origin main
マネジメントコンソールで作業します。
ファイルがアップされていることを確認します。
◆CodeCommit -> ソース -> リポジトリ -> tutorial-app-back
3-5. API 設定を分離
この後認証設定などをやりやすくするため、 API の作りをデフォルトから少し変えておきます。
VSCode のターミナルで作業します。
バックエンド用ディレクトリ(C:\work\tutorial-app\tutorial-app-back)にいる前提で進めていきます。
template.yaml を修正します。
- getAllItemsFunction / getByIdFunction / putItemFunction それぞれの Events の最後に 2 行「RestApiId」設定を追加する
- SampleTable の後、Outputs の前に API Gateway の設定を追加
- Outputs の WebEndpoint の値を変更
template.yaml
# getAllItemsFunction / getByIdFunction / putItemFunction # それぞれの Events の最後に 2 行追加する getAllItemsFunction: Type: AWS::Serverless::Function Properties: # ~ 略 ~ Events: Api: Type: Api Properties: Path: / Method: GET RestApiId: # 追加 Ref: SampleApi # 追加 # ~ 略 ~ SampleTable: Type: AWS::Serverless::SimpleTable Properties: PrimaryKey: Name: id Type: String ProvisionedThroughput: ReadCapacityUnits: 2 WriteCapacityUnits: 2 # ↓ ----- 追加 ----- ↓ # -------------------- # API Gateway # -------------------- SampleApi: Type: AWS::Serverless::Api Properties: Name: "tutorial-app-api" StageName: dev OpenApiVersion: 3.0.2 EndpointConfiguration: REGIONAL # ↑ ----- 追加 ----- ↑ Outputs: WebEndpoint: Description: "API Gateway endpoint URL for dev stage" # 変更 Value: !Sub "https://${SampleApi}.execute-api.${AWS::Region}.amazonaws.com/dev" # 変更
template.yaml の変更が終わったら、ビルド/デプロイをします。
sam build
sam deploy --config-env dev
さきほど sam deploy --guided でデプロイした際の「SAM configuration environment」で設定した環境名を引数に入れることで、その時作成した設定ファイルでデプロイされます。
※環境名を default で作成した場合は「sam deploy」のみで OK
3-6. 修正後のバックエンド API 動作確認
デプロイが完了したら、API Gateway の画面で動作確認をしておきましょう。
マネジメントコンソールで作業します。
◆API Gateway -> API
「tutorial-app-api」という名前の API を開きます。(最初の API とは名前が変わっていますので注意)
POST -> テスト をクリックして、リクエスト本文に以下を入力し、「テスト」ボタンをクリックしてデータを登録しましょう。
※リクエスト本文
{ "id": "id2", "name": "name2" }
次に、 GET -> テスト -> テスト をクリックして、結果が返ってくることを確認しましょう。
DynamoDB にもデータが登録されているかどうか確認しましょう。
◆DynamoDB -> テーブル -> tutorial-app-back-stack-SampleTable-<ランダム文字列>
テーブルアイテムの検索 をクリックして、データが登録されていることを確認します。
修正後の API でもデータが登録/参照できることが確認できました。
ここまでをリポジトリに Push しておきましょう。
git add template.yaml git commit -m "API を共通化" git push origin main
バックエンドの API 実装が完了しました。
次回はフロントエンドを実装してきます。
4. 参考
AWS CloudFormation(テンプレートを使ったリソースのモデル化と管理)| AWSAWS サーバーレスアプリケーションモデル - アマゾン ウェブ サービス