[PYTHON] [AWS SAM] Créer une API avec DynamoDB + Lambda + API Gateway

Contenu

Créons une API qui récupère les données DynamoDB avec AWS SAM

Bref, à partir d'une table comme celle-ci ...

group(Hash) name(Range)
group1 name1
group1 name2
group2 name3

Je veux prendre ça comme ça.

curl https://hogehoge/Prod/dynamo-api/v1/?group=group1&name=name1

{
    "result": [
        {
            "name": "group1",
            "group": "name1"
        }
    ]
}

environnement

table des matières

  1. Construction de l'environnement d'application
  2. Écrivez template.yaml
  3. Ecrire un script d'exécution
  4. Déployer
  5. Vérification

1. Construction de l'environnement d'application

Pour la construction, reportez-vous à la précédente [AWS SAM] Introduction à la version Python. (Il s'agit de la procédure d'initialisation d'une application AWS SAM à l'aide de Pipenv.)

2. Écrivez template.yaml

Ressource

Les ressources à créer cette fois sont les suivantes

Définition des ressources

Maintenant, écrivons template.yaml pour créer les ressources ci-dessus.

template.yaml


AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  dynamo-api

  Sample SAM Template for dynamo-api

#Paramètres de délai d'expiration Lambda
Globals:
  Function:
    Timeout: 60

#Définition du nom de la table, du nom de la fonction, etc.
Parameters:
  DynamoAPIFunctionName:
    Type: String
    Default: dynamo-api
  DynamoTableName:
    Type: String
    Default: DynamoApiTable

#Définition des ressources
Resources
  DynamoTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: !Ref DynamoTableName
      #Définition de la clé de hachage et de la clé de plage (nom et type de colonne)
      AttributeDefinitions:
        - AttributeName: group
          AttributeType: S
        - AttributeName: name
          AttributeType: S
      KeySchema:
        - AttributeName: group
          KeyType: HASH
        - AttributeName: name
          KeyType: RANGE
      #Désignation du mode de charge (PAY_PER_REQUEST est pay-as-you-go)
      BillingMode: PAY_PER_REQUEST

  DynamoAPIFunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - 'lambda.amazonaws.com'
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess'
      #Autorisation de lire la table DynamoDB (cela vous permet de lire uniquement la table que vous créez cette fois)
      Policies:
        - PolicyName: 'DynamoApiTablePolicy'
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - dynamodb:Get*
                  - dynamodb:Query
                Resource: !GetAtt DynamoTable.Arn

  DynamoAPIFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Ref DynamoAPIFunctionName
      Role: !GetAtt DynamoAPIFunctionRole.Arn
      # app.Chemin du répertoire où se trouve py
      CodeUri: dynamo-api/
      #Chemin du gestionnaire (il est facile de se tromper si vous le changez négligemment ... c'est bien de le laisser tranquille)
      Handler: app.lambda_handler
      Runtime: python3.7
      #Paramètres de la passerelle API (description spécifique à SAM)
      Events:
        DynamoApi:
          Type: Api
          Properties:
            Path: /dynamo-api/v1/
            Method: get

#Le rôle d'origine des paramètres spécifiés dans Outputs est de transmettre des données à d'autres modèles.
#Cette fois, il est utilisé pour générer le point de terminaison de l'API lorsque le déploiement est terminé.
Outputs:
  DynamoApi:
    Description: "API Gateway endpoint URL for Prod stage for Dynamo API function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/dynamo-api/v1/"

Les paramètres de Lambda et d'API Gateway sont presque identiques à ceux du modèle, il est donc facile à écrire.

3. Ecrire un script d'exécution

Installation de la bibliothèque

Tout d'abord, installez les bibliothèques requises.

$ pipenv install requests boto3

Écrire le traitement de l'API

Ensuite, nous allons créer un processus qui récupère réellement les données de la table Dynamo. Recherchez la table Dynamo avec le groupe et le nom` spécifiés dans le paramètre GET et renvoyez sa valeur C'est un mécanisme simple. J'ai essayé de faire de «nom» le premier.

app.py


import json
import json
import boto3
from boto3.dynamodb.conditions import Key
from http import HTTPStatus as status


DYNAMODB_TABLE_NAME = 'DynamoApiTable'


def lambda_handler(event, context):

    table = boto3.resource('dynamodb').Table(DYNAMODB_TABLE_NAME)

    params = event.get('queryStringParameters')

    results = dynamo_search(table, params)

    if results is None:
        return {
            "statusCode": status.BAD_REQUEST,
            "body": json.dumps({
                "error": "Bad Request"
            }, ensure_ascii=False),
        }

    return {
        "statusCode": status.OK,
        "body": json.dumps({
            "results": results
        }, ensure_ascii=False),
    }


def dynamo_search(table, params):
    if params.get('group'):
        keyConditionExpression = Key('group').eq(params.get('group'))
        if params.get('name'):
            keyConditionExpression &= Key('name').begins_with(params.get('name'))
        return table.query(
            KeyConditionExpression=keyConditionExpression).get('Items', [])

    return None

4. Déployer

(À part) Pipfile vers requirements.txt

Je veux convertir de Pipfile en requirements.txt ... Dans un tel cas, vous pouvez convertir avec cette commande. (Boto3 est également préparé dans Lambda depuis le début, donc il peut ne pas être beaucoup utilisé ..: penser :)

$ pipenv lock -r > requirements.txt

Cette fois, vous pouvez conserver la valeur par défaut requirements.txt: sweat_smile:

Construire

$ sam build
Building resource 'DynamoAPIFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided

Déployer

Si vous avez des paramètres séparés pour ~ / .aws / credentials, ajoutez l'option --profile. L'option --guided n'est valide que pour la première fois. (Parce que les paramètres sont enregistrés dans samconfig.toml)

$ sam deploy --guided
Stack dynamo-api-stack outputs:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
OutputKey-Description                                                                                 OutputValue                                                                                         
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
DynamoApi - API Gateway endpoint URL for Prod stage for Dynamo API function                           https://hogehoge/Prod/dynamo-api/v1/                     
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Le point de terminaison est également affiché correctement ~

5. Vérification

Enregistrer les données dans Dynamo

Cette fois (également), j'ai enregistré le nom et le nom du groupe recommandé.

group(Hash) name(Range)
Bracelet miel Suo Patra
Bracelet miel Miko Weir
Holo en direct Fubuki Shirakami
... ...

Essayez d'accéder à l'API

Essayez d'envoyer une demande au point de terminaison de sortie. C'est difficile à voir, alors formatez-le avec jq. (Les gens dans le navigateur parce que curl est gênant: information_desk_person :)

Tout d'abord, spécifiez group (clé de hachage).

$ curl https://hogehoge/Prod/dynamo-api/v1/ \
--get \
--data-urlencode 'group=Bracelet miel' | jq

{
  "results": [
    {
      "name": "Suo Patra",
      "group": "Bracelet miel"
    },
    {
      "name": "Miko Weir",
      "group": "Bracelet miel"
    },
    {
      "name": "Charlotte Shimamura",
      "group": "Bracelet miel"
    },
    {
      "name": "Saizonoji Mary",
      "group": "Bracelet miel"
    }
  ]
}

Je l'ai: clap:

Bien sûr, vous pouvez également rechercher nom (clé de plage) avec une correspondance de préfixe.

$ curl https://hogehoge/Prod/dynamo-api/v1/ \
--get \
--data-urlencode 'group=Bracelet miel' \
--data-urlencode 'name=Suo' | jq
{
  "results": [
    {
      "name": "Suo Patra",
      "group": "Bracelet miel"
    }
  ]
}

Je l'ai, c'est parfait!

À la fin

Cette fois, j'ai fait une API simple. La prochaine fois, je testerai avec pytest. Merci d'avoir lu jusqu'au bout!

Dernière fois

[AWS SAM] Présentation de la version Python

Recommended Posts

[AWS SAM] Créer une API avec DynamoDB + Lambda + API Gateway
[AWS] Créer une API avec API Gateway + Lambda
Créez rapidement une API avec Python, lambda et API Gateway à l'aide d'AWS SAM
API REST facile avec API Gateway / Lambda / DynamoDB
LINE BOT avec Python + AWS Lambda + API Gateway
[AWS] Essayez de tracer API Gateway + Lambda avec X-Ray
Envoyer les images prises avec ESP32-WROOM-32 vers AWS (API Gateway → Lambda → S3)
Comment créer une API de machine learning sans serveur avec AWS Lambda
Afficher les images sur S3 avec API Gateway + Lambda
Application sans serveur avec AWS SAM! (APIGATEWAY + Lambda (Python))
Version Amazon API Gateway et AWS Lambda Python
Essayez d'implémenter un robot Cisco Spark avec AWS Lambda + Amazon API Gateway (Python)
[AWS] Play with Step Functions (SAM + Lambda) Part.3 (Branch)
Créer une couche pour AWS Lambda Python dans Docker
[AWS] Play with Step Functions (SAM + Lambda) Part.1 (Basic)
[AWS] Play with Step Functions (SAM + Lambda) Part.2 (Paramètres)
Créer une API avec Django
AWS CDK-Lambda + API Gateway (Python)
PyTorch avec AWS Lambda [importation Lambda]
Prenez rapidement une chaîne de requête avec API Gateway-> Lambda (Python)
[AWS] Essayez d'ajouter la bibliothèque Python à la couche avec SAM + Lambda (Python)
Créer Awaitable avec l'API Python / C
Créez une API en utilisant hug avec mod_wsgi
Notifier HipChat avec AWS Lambda (Python)
Créez un alias pour Route53 vers CloudFront avec l'API AWS
J'ai essayé ChatOps avec Slack x API Gateway x Lambda (Python) x RDS
[Python] J'ai écrit une API REST en utilisant AWS API Gateway et Lambda.
Créer une API REST pour faire fonctionner dynamodb avec le Framework Django REST
Créer une liste d'utilisateurs Cognito dans S3 avec SQS Déployer des fonctions de traitement de file d'attente et des API sur Lambda avec SAM
J'ai essayé de supprimer régulièrement les mauvais tweets avec l'API AWS Lambda + Twitter
Créez automatiquement la documentation de l'API Python avec Sphinx
[AWS] Créez un environnement Python Lambda avec CodeStar et faites Hello World
Créons une fonction de chat avec Vue.js + AWS Lambda + dynamo DB [Paramètres AWS]
Manipulation des données DynamoDB avec Lambda (Node et Python)
J'ai essayé de créer un LINE BOT "Sakurai-san" avec API Gateway + Lambda
Présentation du mécanisme Twilio # 3-1 - Procédure pas à pas de mise en œuvre de la passerelle API API + Lambda (partie 1)
[AWS] Associez Lambda et S3 à boto3
[Python] Créez rapidement une API avec Flask
Connectez-vous à s3 avec AWS Lambda Python
Créer un bloc de page / Todo avec l'API Notion
Créer un référentiel privé avec AWS CodeArtifact
[AWS] Faites des choses de type SSI avec S3 / Lambda
Je viens de faire FizzBuzz avec AWS Lambda
Créez un bot avec AWS Lambda qui démarre / arrête automatiquement les instances avec des balises spécifiques
Grattage sans serveur régulier avec AWS lambda + scrapy Part 1.8
J'ai essayé de connecter AWS Lambda à d'autres services
Automatisation de la construction de l'infrastructure avec CloudFromation + troposphère + AWS Lambda
Transmettre Cognito Id à Lambda via API Gateway
Créez rapidement un serveur API avec Python + Falcon
Remarque pour le traitement des données POST en se connectant à Lambda via la passerelle API d'AWS (API HTTP)
Pages HTML dynamiques créées avec AWS Lambda et Python
Créez Amazon Linux avec AWS EC2 et connectez-vous
Créer une fonction Lambda de version Python (+ couche Lambda) avec Serverless Framework
Comment configurer Layer sur Lambda à l'aide d'AWS SAM
Déployer la fonction Python 3 avec Serverless Framework sur AWS Lambda
Écrire plusieurs enregistrements dans DynamoDB avec Lambda (Python, JavaScript)