[PYTHON] L'histoire selon laquelle l'API asynchrone qui combinait API Gateway et Step Functions était la plus forte

Est-ce le plus fort ou le plus facile?

Commun en tant que configuration sans serveur Passerelle API et Lambda

** API Gateway a une limite de 29 secondes **, ** Lambda a une limite de 15 minutes **

Tout en exploitant pleinement les performances de Lambda Pour combler cette lacune ** Je souhaite créer une API asynchrone avec une configuration aussi simple que possible ** Je pense que oui.

Ce dont vous avez besoin à ce moment-là

--API pour botter Lambda --API pour déterminer si le Lambda expulsé est terminé et recevoir une réponse

Je pense que oui, mais les fonctions d'étape ci-dessous ont les deux **

Step Functions

Fonctions d'étape Rendre le flux de travail visuellement et beau, comme la liaison de micro-services Peut être configuré.

** Exemple officiel: ** image.png

https://aws.amazon.com/jp/blogs/news/new-aws-step-functions-build-distributed-applications-using-visual-workflows/

C'est dangereux Je pense que je peux tout faire

En définissant Lambda comme une tâche Vous pouvez l'intégrer dans ce flux de travail.

Au fait, c'est celui que je vais faire cette fois (mignon)

image.png

Créer une passerelle API

image.png

Je vais le faire comme ça

API pour démarrer l'exécution pour lancer le Lambda ci-dessus API pour l'exécution de la description pour recevoir la réponse de "Lambda" (Le nom peut être n'importe quoi)

** Les deux sont POST **

Serverless Framework

https://github.com/ChaseSan/async-api-sample

Je vais vraiment réussir avec SLS C'est beaucoup plus facile que de le faire avec CFn, Vous devez inclure `` serverless-step-functions '' en tant que plug-in

serverless.yml


plugins:
  - serverless-step-functions

La fonction est créée comme ceci ** Minuterie Ramen **

serverless.yml


functions:
  async-api:
    handler: app.lambda_handler
    name: async-api-${self:provider.stage}
    environment:
      TIMER: 30

app.py


import os
from time import sleep
import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)


def lambda_handler(event, context):
    logger.info(f"event: {event}")

    seconds = int(os.environ.get("TIMER"))
    sleep(seconds)

    return {"message": "Le ramen est bouilli, si vous ne le mangez pas rapidement, il poussera."}

La définition des fonctions d'étape ressemble à ceci Lors de l'utilisation du plugin serverless-step-functions Écrivez également la définition de la passerelle API dans le bloc stateMachines

serverless.yml


stepFunctions:
  stateMachines:
    state-machine:
      name: state-machine-${self:provider.stage}
      events:
        - http:
            path: ${self:custom.basePath}/start-execution
            method: post
            action: StartExecution
            iamRole:
              Fn::GetAtt: [AsyncApiRole, Arn]
            request:
              template:
                application/json: |-
                  {
                    "stateMachineArn":"arn:aws:states:#{AWS::Region}:#{AWS::AccountId}:stateMachine:state-machine-${self:provider.stage}"
                  }
        - http:
            path: ${self:custom.basePath}/describe-execution
            method: post
            action: DescribeExecution
            iamRole:
              Fn::GetAtt: [AsyncApiRole, Arn]
            response:
              template:
                application/json: |-
                  {
                    "input": $util.parseJson($input.json('$.input')),
                    #if($input.path('$.output') != "")
                      "output": $util.parseJson($input.json('$.output')),
                    #end
                    "status": $input.json('$.status')
                  }
      definition:
        StartAt: async-api-task
        States:
          async-api-task:
            Type: Task
            Resource:
              Fn::GetAtt: [async-api, Arn]
            End: true

** Points **

--Dans start-execution, décrivez StartExecution dans ʻevents.http.action. --ʻEvents.http.request.template décrit Arn of State Machine à exécuter au format Json. --Dans describe-execution, décrivez DescribeExecution dans ʻevents.http.action. --Description de la réponse au format Json dans ʻevents.http.request.template

{
    "response": $input.json('$'),
}

Quoi qu'il en soit, tout le contenu de DescribeExecution sera retourné. Il vaudrait mieux ne renvoyer que ce dont vous avez besoin en termes d'interface (probablement)

bouge toi

Déployons et bougeons sls deploy image.png Essayez-le avec le point de terminaison qui apparaît sur la console

start-execution image.png Utilisez le ʻexecutionArn` obtenu pour accéder à l'API suivante

describe-execution image.png

Quelque chose est revenu. «status» est «EN COURS». Il semble que les ramen n'aient pas encore été préparés.

Revenons après un moment image.png

Oh, «statut» est devenu «RÉUSSITE», et vous m'avez dit que le ramen était terminé.

c'est tout

Non, c’est vraiment facile. Sans cela, je devrais utiliser pleinement Dynamo et SQS et les implémenter moi-même (enfer).

Recommended Posts

L'histoire selon laquelle l'API asynchrone qui combinait API Gateway et Step Functions était la plus forte
L'histoire que XGBoost a finalement été installé
Une histoire que Seaborn était facile, pratique et impressionnée
Exemples PHP et Python qui ont atteint l'API ChatWork
L'histoire selon laquelle la valeur de retour de tape.gradient () était None
L'histoire de la confusion entre la production japonaise et Django
L'histoire selon laquelle ma pull request a été intégrée à Scipy
L'histoire selon laquelle la nouvelle bibliothèque de dessins "HiPlot" était plutôt bonne
API Zabbix ceci et cela
L'histoire selon laquelle la version de python 3.7.7 n'était pas adaptée à Heroku
L'histoire selon laquelle l'environnement Homebrew a été époustouflé lors de l'installation d'Anaconda
L'histoire selon laquelle le gardien était confiné lorsque le laboratoire a été converti à l'IoT