2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Qiita100万記事感謝祭!記事投稿キャンペーン開催のお知らせ

【サーバレス】API GatewayとLambda(Python)を使ってDynamoDBへ読書きをする

Posted at

今回も何番煎じか分かりませんが以下AWSハンズオンの構成をお試し構築していきます。本件は私のようなサーバレス構成に慣れていない方でもできる比較的簡単な内容(だと思います)です。

チュートリアル: Lambda と DynamoDB を使用して CRUD HTTP API を作成する

今回のゴール

PCからの指定URLへのHTTPリクエストで、サーバレスにDynamoDB への書き込みとDynamoDB からのデータ読み込みができるようにする。構成は以下のようなイメージです。

スライド22.PNG

ちなみに「CRUD」とは…

CRUDとは、データベース管理システム(DBRS)に必要とされる4つの主要な機能、「作成(Create)」「読み出し(Read)」「更新(Update)」「削除(Delete)」をそれぞれ頭文字で表したもののことである。

だそうです。

【出典】

前提条件(+免責事項)

  • 当方では動作保証はしていません。何か質問があればAWSサポートまで。
  • リソースへのアクセス許可設定のためIAMロールなどのAWS権限設定できるIAMユーザアカウントが必要になります。
  • Lambdaは記載時最新のPython3.13で記載します。
  • リソース利用で料金がかかります。環境構築後に本環境が不要になった場合、リソースの削除をお忘れなく。

HTTP APIとRest APIの違い

他の方の記事、ブログなどでRest APIで構築されている場合もありますが本記事はハンズオン資料に沿って、HTTP APIで設定します。HTTP APIとRest APIの違いですがこんな感じです。

Rest API HTTP API
AWS WAF利用OK AWS WAF利用NG
相互認証TLS利用OK 相互認証TLS利用NG
カスタムドメイン利用OK カスタムドメイン利用OK
費用:標準 費用:低め

[参照]
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/http-api-vs-rest.html

設定の流れ

①DynamoDBのテーブル作成

まずはデータベースとなるDynamoDBを構築していきます。

今回テーブル名は「http-crud-tutorial-items」、パーティションキーは「id」で登録します。
ソートキーは設定なしで、テーブル設定は「デフォルト」で設定します。

スライド1.PNG

これでDynamoDBのテーブルを作成します。

②Lambda関数の設定

次にLambda関数の設定を行います。今回はテンプレートは使わないので「一から作成」を選択し、関数名には「http-crud-tutorial-function」と入力します。ランタイムはPython 3.13を選択します。

image.png

デフォルトの実行ロールの変更で「AWSポリシーテンプレートから新しいロールを作成」を選択し、ロール名には「http-crud-tutorial-role」を、ポリシーテンプレートでは「シンプルなマイクロサービスのアクセス権限」を選択し、作成します。

スライド2.PNG

関数の作成が完了したらPythonコードを記述していきます。

image.png

記述内容は下記です。

import json
import boto3
from decimal import Decimal

client = boto3.client('dynamodb')
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table('http-crud-tutorial-items')
tableName = 'http-crud-tutorial-items'


def lambda_handler(event, context):
    print(event)
    body = {}
    statusCode = 200
    headers = {
        "Content-Type": "application/json"
    }

    try:
        if event['routeKey'] == "DELETE /items/{id}":
            table.delete_item(
                Key={'id': event['pathParameters']['id']})
            body = 'Deleted item ' + event['pathParameters']['id']
        elif event['routeKey'] == "GET /items/{id}":
            body = table.get_item(
                Key={'id': event['pathParameters']['id']})
            body = body["Item"]
            responseBody = [
                {'price': float(body['price']), 'id': body['id'], 'name': body['name']}]
            body = responseBody
        elif event['routeKey'] == "GET /items":
            body = table.scan()
            body = body["Items"]
            print("ITEMS----")
            print(body)
            responseBody = []
            for items in body:
                responseItems = [
                    {'price': float(items['price']), 'id': items['id'], 'name': items['name']}]
                responseBody.append(responseItems)
            body = responseBody
        elif event['routeKey'] == "PUT /items":
            requestJSON = json.loads(event['body'])
            table.put_item(
                Item={
                    'id': requestJSON['id'],
                    'price': Decimal(str(requestJSON['price'])),
                    'name': requestJSON['name']
                })
            body = 'Put item ' + requestJSON['id']
    except KeyError:
        statusCode = 400
        body = 'Unsupported route: ' + event['routeKey']
    body = json.dumps(body)
    res = {
        "statusCode": statusCode,
        "headers": {
            "Content-Type": "application/json"
        },
        "body": body
    }
    return res

記述が完了したら「DEPLOY」を行います。

③API Gatewayの作成

APIタイプでは「HTTP API」を選択します。

スライド3.PNG

API名は「http-crud-tutorial-api」とします。

スライド4.PNG

いったんルートは設定せずに、「次へ」をクリックします。

スライド5.PNG

ステージ名は「$default」のままでOKなので、「次へ」をクリックし、APIを作成します。
スライド6.PNG

APIが作成されたら、左側のメニューから「Develop」-「Route」を選択し、「作成」をクリックします。
スライド7.PNG

以下の4つのルートを作成します。

メソッド パス
GET /items/{id}
GET /items
PUT /items
DELETE /items/{id}

作成するとこんな感じになります。

スライド8.PNG

スライド9.PNG

④API GatewayとLambda関数の紐づけ

続いて先ほど作成したAPIとLambdaの紐づけを行っていきます。APIの管理画面で左側メニューの「Develop」-「Integrations」を選択し、「統合を管理」から「Create」をクリックします。

スライド10.PNG

先ほど作成した4つのルートすべてに②で作成したLambda関数を紐づけしていきます。
スライド11.PNG

設定するとこんな感じになります。
スライド14.PNG

APIとLambdaの紐づけが完了するとLambda側でも下記のように画面に紐づけが反映されます。

image.png

これで環境構築は完了です。

⑤動作確認

それではちゃんと動作するか確認していきましょう。APIの管理画面の左側メニューの真ん中付近に「API: http-crud-tutor・・・」があるので、そこをクリックします。

スライド15.PNG

「http-crud-tutorial-api のステージ (1)」の下に書かれているURLがAPIにアクセスするURLになります。

PCのコマンドプロンプトで実行してもいいですがせっかくなのでAWS CloudShellで実行したいと思います。コンソールの右上の再生マークの表示があると思うのでクリックしてもらえれば、CloudShellが起動します。

image.png

CloudShellが起動したら以下のコマンドを実行します。このコマンドはHTTPアクセスのPUTメソッドでid=123で、price=1234で、name=myitemというデータを書き込みする内容になっています。

curl -X "PUT" -H "Content-Type: application/json" -d "{\"id\": \"123\", \"price\": 12345, \"name\": \"myitem\"}" https://{「http-crud-tutorial-api のステージ (1)」の下に書かれているURL}

正常に動作した場合はDynamoDBに以下のようにデータが書き込みされます。

スライド16.PNG

次にid=123のデータについて読み取りを行います。

curl https://{「http-crud-tutorial-api のステージ (1)」の下に書かれているURL}/items/123

先ほど登録したデータが読み取れればOKです。ちなみにPCのコマンドプロンプトで実行すると以下のようなレスポンスが表示されます。

PS C:\Users\administrator> curl https://{「http-crud-tutorial-api のステージ (1)」の下に書かれているURL}/items/123


StatusCode        : 200
StatusDescription : OK
Content           : [{"price": 12345.0, "id": "123", "name": "myitem"}]
RawContent        : HTTP/1.1 200 OK
                    Connection: keep-alive
                    Apigw-Requestid: XXXXXXXXXXX
                    Content-Length: 51
                    Content-Type: application/json
                    Date: Mon, 13 Jan 2025 05:17:56 GMT

                    [{"price": 12345.0, "id": "123", ...
Forms             : {}
Headers           : {[Connection, keep-alive], [Apigw-Requestid, XXXXXXXXX=], [Content-Length, 51], [Content-Type
                    , application/json]...}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 51

おわりに

AWSハンズオンには難解はものもありますが、このハンズオンはシンプルで結果も分かりやすいのサーバレス初心者にも優しくて助かります。何となくできるSEになった気分になれますね笑

参考にしたサイト

2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?