[AWS]ハンズオン – はじめてのサーバレス

AWSを少しかじり始めました。
色々ハンズオンを試してみてますが、少し記事が古かったりすると、まともに動かなかったりします。クラウドサービスの仕様の変化は凄まじい。

と言うことで、本記事執筆時点でも動作するように変更も加えてトライしたハンズオンをご紹介します。今回のハンズオンはこちらの「はじめてのサーバーレス」がベースになります。
(リンク先のタイトルは、AWS-Amplify-AWS-Lambda-Amazon-DynamoDB-AWS-API-Gateway-Amazon-Cognitoです。)

ハンズオンの内容は、以下の通りですが、今回の記事では、1.のみを扱っています。

1.サーバーレスアプリケーションをstep-by-stepで構築する 
AWSサービス:
Amazon DynamoDB、AWS Lambda、Amazon API Gateway、Amazon Cognito

2.Amplifyを使ってサーバーレスアプリケーションを構築する
AWSサービス:
AWS Amplify、Amazon DynamoDB、AWS Lambda、Amazon API Gateway、Amazon Cognito

では始めていきます。

はじめてのサーバーレス」の案内通りにセットアップを進めて行きますが、
4.1.4. Lambda関数の作成とテスト(Write関数) 
この箇所で躓くことになります。指示に従い、関数の作成とデプロイを実行するのですが、以下のようなエラーが発生します。

{
"errorType": "ReferenceError",
"errorMessage": "require is not defined in ES module scope, you can use import instead",
"trace": [
"ReferenceError: require is not defined in ES module scope, you can use import instead",

これは、端的に言ってしまうと、requireではなく、importを使えと言う事なんですが、元々のハンズオン記事が作成されたのは2021年、この当時は、JavaScriptのAWS SDKのバージョンはV2でしたが、今現在は、V3になっています。
その仕様等については、こちらのページ「https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/welcome.html」に掲載されており、そこに以下のような記載があります。

SDK for JavaScript (V2) のバージョン2では、AWSのSDK全体を、以下の様に使用する必要がありました。

var AWS = require("aws-sdk");

アプリケーションが多くのAWSのサービスを使用している場合、SDK 全体のロードは問題はありません。ただし、わずかのAWSのサービスしか使用する必要がない場合、不要なコードや使用しないコードを使用してアプリケーション数を増やすことを意味します。

V3では、必要な個々のAWSサービスのみをロードして使用できます。これを次の例に示します。これにより、Amazon DynamoDB(DynamoDB)にアクセスできます。

import { DynamoDB } from "@aws-sdk/client-dynamodb";

個別のAWSのサービスを読み込んで使用することができるだけでなく、必要なサービスコマンドだけを読み込んで使用することもできます。これを次の例でDynamoDB クライアントとListTablesCommandコマンドにアクセスできることを示しています。

import {
DynamoDBClient,
ListTablesCommand
} from "@aws-sdk/client-dynamodb";

これに基づき、以下のようにコードを修正しました(write処理のコード)。

console.log('Loading function');

import { DynamoDBClient, PutItemCommand } from '@aws-sdk/client-dynamodb';
import { marshall } from '@aws-sdk/util-dynamodb';

const client = new DynamoDBClient({ region: 'ap-northeast-1' });//ご自身の環境のリージョンを指定

export const handler = async (event) => {
    console.log('Received event:', JSON.stringify(event, null, 2));

    const params = {
        TableName: 'serverless202404',//ご自身の環境に合わせたテーブル名を指定
        Item: marshall({
            Artist: event.artist,
            Title: event.title
        })
    };

    try {
        const command = new PutItemCommand(params);
        const data = await client.send(command);
        console.log('Success', data);
        return data;
    } catch (err) {
        console.log('Error', err);
        throw new Error(err);
    }
};


同様にread処理も以下のように修正しました。

console.log('Loading function');

import { DynamoDBClient, QueryCommand } from '@aws-sdk/client-dynamodb';
import { marshall } from '@aws-sdk/util-dynamodb';

const client = new DynamoDBClient({ region: 'ap-northeast-1' });//ご自身の環境のリージョンを指定

export const handler = async (event) => {
    console.log('Received event:', JSON.stringify(event, null, 2));

    const params = {
        TableName: 'serverless202404',//ご自身の環境に合わせたテーブル名を指定
        KeyConditionExpression: 'Artist = :artist',
        ExpressionAttributeValues: marshall({
            ':artist': event.artist
        })
    };

    try {
        const command = new QueryCommand(params);
        const data = await client.send(command);
        console.log('Success', data);

        const formattedData = data.Items.map(item => {
            return {
                Title: item.Title.S,
                Artist: item.Artist.S
            };
        });

        return formattedData;
    } catch (err) {
        console.log('Error', err);
        throw new Error(err);
    }
};

これで、私の環境では問題なく動作するようになりました。
ご参考になれば幸いです。

なお、後続の「2.Amplifyを使ってサーバーレスアプリケーションを構築する」については、まだ試行錯誤中です。
少なくとも、
・resize.sh がうまく動作しない可能性あり。
→最新のシェルが公開されています。こちら
https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/move-environment.html#move-environment-resize

・nodeのバージョン確認
 node —version で動作しなければ、node version で

・npm startでエラー発生

Attempted import error: 'API' is not exported from 'aws-amplify' (imported as 'API').
ERROR in ./src/ApiGet.js 33:4-11
export 'API' (imported as 'API') was not found in 'aws-amplify' (possible exports: Amplify)
他のjsファイルも同様のエラー

こちらは以下対策を
import {API} from ‘aws-amplify’; を import {Amplify} from ‘aws-amplify’;に変更、及び
API.get(config.apiName, path, init) をAmplify.API.get(config.apiName, path, init) に
※import {Amplify}と{}で囲むことが重要。
参考:https://qiita.com/seigot/items/ae37ae3d905156f87a73

が、これ以降がうまく行っておりません。
進展あればまたエントリーしたいと思います。
また、参考情報等、お持ちの方いらっしゃればご教示頂ければ幸いです。

カテゴリーAWS

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です