5
0

More than 1 year has passed since last update.

AmplifyでAWS Serverless Expressを使用してCRUD処理を行う

Last updated at Posted at 2022-12-05

ACCESS Advent Calendar 2022 の6日目になります。

この記事は、幅広いAWSサービスを活用できるプラットフォームのAWS Amplifyで、LambdaをExpressで構築できるAWS Serverless Express を使用して、DynamoDBと接続、その上でCRUD処理を行う書き方についてとなります。
参考となった記事は「Create a REST API integrated with Amazon DynamoDB using AWS Amplify and Vue」となります。ほぼその記事通りの実装となります。

環境構築

LambdaでCRUD処理を書く前に環境を構築します。

各packageとAmplifyのversion

"aws-sdk": "2.1253.0",
"aws-serverless-express": "3.4.0",
"express": "4.18.2"
"Amplify CLI": "10.5.1"

ポリシー設定

CRUD処理を行う前提として、LambdaからDynamoDBにアクセスするための権限が必要となります。
そこでポリシーを設定します。
$ amplify add api を実行した後、amplify/backend/function/{functionName}custom-policies.json が自動で作成されます。
そのファイルに記述することで、Lambda関数でDynamoDBにデータが反映されます。

custom-policies.json
[
    {
        "Action": [
            "dynamodb:PutItem", // POST
            "dynamodb:Scan", // GET ALL
            "dynamodb:GetItem", // GET ONE
            "dynamodb:UpdateItem", // UPDATE
            "dynamodb:DeleteItem" // DELETE
        ],
        "Resource": ["arn:aws:dynamodb:*:*:table/{tableName}"],
        "Effect": "Allow"
    }
]

AWS Serverless Expressを使用

LambdaをExpressで構築することができます。
それは $ amplify add api で、設定についての質問の

Choose the function template that you want to use

で、Serverless ExpressJS function (Integration with API Gateway) を選択するとExpressで構築されたfunctionのSampleファイルが自動で作成されるので、それを見本に構築します。

DynamoDBに接続

次にDynamoDBをAmplifyで使用するには storage を追加した上で、さらにfunction をupdateします。

$ amplify add storage
$ amplify update function

その上でLamda関数を定義するファイルで DocumentClient を読み込むと、DynamoDBと接続されます。

import AWS from 'aws-sdk';
const dynamodb = new AWS.DynamoDB.DocumentClient();

その DocumentClient を読み込んだ変数 dynamodb に各CRUD処理のメソッドを定義します。
例えばPOSTの場合は

POST例
dynamodb.put(params, (error, result) => {
    if (error) {
        // errorのresponseを書く
    } else {
        // 正常のresponseを書く
    }
});

となります。
その他のCRUD処理のメソッドは下記になります。

dynamodb.scan // GET ALL
dynamodb.get // GET ONE
dynamodb.update // UPDATE
dynamodb.delete // DELETE

環境構築のおおよその設定をイメージできたのではないでしょうか。
次にCRUD処理の書き方について説明します。

CRUD処理の書き方

paramsについて

前述の POST例 でput関数の引数に params を設定しました。
その params は、公式ドキュメント「Calling DynamoDB from Lambda in Node.js」に記載されてるとおり、いくつかの keyvalue を指定することができます。

const params = {
    TableName : 'your-table-name',
    IndexName: 'some-index',
    KeyConditionExpression: '#name = :value',
    ExpressionAttributeValues: { ':value': 'shoes' },
    ExpressionAttributeNames: { '#name': 'name' }
    Item: {
        id: '12345',
        price: 100.00
    }
    Key: {
        id: '12345'
    }
    ReturnValues: NONE | ALL_OLD | UPDATED_OLD | ALL_NEW | UPDATED_NEW
}

Item はDynamoDBに登録するデータになります。
さらに Key は既に登録済みのデータを抽出する際に指定します。とても直感的で分かりやすいですね。
例えばDynamoDBに1件新規で登録する場合は

POST例
const postUser = (request, response) => {
    const timestamp = new Date().toISOString();
    const params = {
        TableName: tableName,
        Item: {
            ...request.body,
            id: uuidv4(),
            createdAt: timestamp,
            updatedAt: timestamp,
        },
    };
    
    dynamodb.put(params, (error, result) => {
        if (error) {
            // errorのresponseを書く
        } else {
            // 正常のresponseを書く
        }
    });
};

となります。
次にDynamoDBに登録されているデータを1件抽出する場合は

GET ONE例
const getOneUser = (request, response) => {
    const params = {
        TableName: tableName,
        Key: {
            id: request.params.userId,
        },
    };
  
    dynamodb.get(params, (error, result) => {
        if (error) {
            // errorのresponseを書く
        } else {
            // 正常のresponseを書く
        }
    });
};

となります。
さらにDynamoDBに登録されているデータを1件削除する場合は

DELETE例
const deleteUser = async (request, responss) => {
    const params = {
        TableName: tableName,
        Key: {
            id: request.params.userId,
        },
    };

    dynamodb.delete(params, (error, result) => {
        if (error) {
            // errorのresponseを書く
        } else {
            // 正常のresponseを書く
        }
    });
};

となります。

UPDATE処理

UPDATE処理は前述の処理と比較すると少し複雑です。
UPDATE処理には前述した params

  • UpdateExpression
  • ExpressionAttributeValues
  • ExpressionAttributeNames
    を使用します。
    その中のUpdateExpression について、公式サイト「Update expressions」で確認すると
SET — modifying or adding item attributes
REMOVE — deleting attributes from an item
ADD — updating numbers and sets
DELETE — removing elements from a set

を指定することができます。
そこで SET を利用して

UpdateExpression: 'SET #attributeName = :attributeValue'

と設定します。
この書き方については、「DynamoDBでデータを更新する際に使うUpdateExpressionについて一通りまとめてみた」の記事に記載されいてるとおり、

UpdateExpressionの中では #xxxなど#で始まる変数でAttributeNameを表現できる。 また、:xxxなど:で始める変数で値を表現ができる。

となります。
つまり、paramsでExpressionAttributeValuesExpressionAttributeNames の ExpressionAttributeNames はDynamoDBに登録する項目の属性名、ExpressionAttributeValues はその属性名に登録する値になります。

UpdateExpression: 'SET #attributeName = :attributeValue'
ExpressionAttributeNames: {
    '#attributeName': {属性名},
},
ExpressionAttributeValues: {
    ':attributeValue': {},

と指定します。
具体的に例を書くと

UPDATE例
const updateUser = (request, response) => {
    const timestamp = new Date().toISOString();
    const params = {
        TableName: tableName,
        Key: {
            id: request.params.userId,
        },
        UpdateExpression: 'SET #title = :title,  #updatedAt = :updatedAt',
        ExpressionAttributeNames: {
            '#title': 'title',
            '#updatedAt': 'updatedAt',
        },
        ExpressionAttributeValues: {
            ':title': request.body.title,
            ':updatedAt': timestamp,
        },
    };
    
    dynamodb.update(params, (error, result) => {
        if (error) {
            // errorのresponseを書く
        } else {
            // 正常のresponseを書く
        }
    }
};

になります。
こう書くことで、DynamoDBに既に登録されているid request.params.userId に対して titleupdateAt の値のみ変更になります。

以上となります。
いかがでしたでしょうか。
AmplifyでCRUD処理を行う際の簡単な説明とSampleコードについて書きました。
そこまで行き着くまでに、AmplifyやAWSのドキュメント、さらには参考記事を読み解く必要があるので、この記事で1つにまとめました。
一助となれば幸いです。

参考サイト

5
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
5
0