サーバーレスWebサイトのサーバーレスフォームを作成する

S3 + CloudFrontは、静的Webサイトをホストするためのシンプルで低コストのソリューションを提供します。ただし、HTMLフォームが必要な場合はどうなりますか?この目的のために、単純なサーバーレスバックエンドの実装について説明します。

序章

AWS S3 + Cloudfrontは、スタートアップのランディングページやニュースレターのサインアップページなどの静的なウェブサイトをホストするための低コストでスケーラブルなオプションを提供します。しかし、サーバーなしでフォームを実装するにはどうすればよいでしょうか。

この記事では、AWSのLambdaAPI Gatewayを使用してフォームのサーバーレスバックエンドを調べ、フォームから入力された情報を含むメールをAWSSESを使用して所定のメールに送信するようにトリガーします。

前提条件

Lambdaのコードに飛び込む前に、開発環境とAWSアカウントをセットアップする必要があります。これには以下のポイントが含まれます。

  1. AWSサーバーレスアプリケーションモデル(SAM)ローカル開発ツールは、こちらの手順に従ってインストールされます。
  2. AWS SESは(サンドボックスではなく)本番モードで設定されており、ドメインはこちらの手順に従って確認されています。
  3. この記事の後半で作成されるAPIゲートウェイのエンドポイントにデータを送信するように構成できるHTMLフォームを備えたWebサイトを用意します。

実装

SAMを使用してLambdaとその依存リソースをデプロイします。SAMの詳細については、以下の記事を参照してください。

SAMを使用したAWSLambdaを使用したプライベートサーバーレスRESTAPI

フォルダ構造から始めましょう。アプリケーションソースファイル用のディレクトリ、アプリケーションの展開に使用できるスクリプト用のディレクトリ、およびtemplate.yamlSAMで使用されるようなトップレベルファイル用のディレクトリがあります。

my-serverless-form/
├── cmd/
│   └── deploy.sh
├── src/
|   ├── package.json
│   └── index.js
├── .gitignore 
└── template.yaml

は次のtemplate.yamlようになります。

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
  serverless-form
  SAM project for serverless-form
Parameters:
  LambdaVersion:
    Default: "not-specified"
    Description: "What is the current code version?"
    Type: String

Resources:
  FormSubmissionFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/
      Handler: index.handler
      Runtime: nodejs12.x
      MemorySize: 128
      Timeout: 3
      Environment:
        Variables:
          LAMBDA_VERSION: !Ref LambdaVersion
      Policies:
        - AWSLambdaBasicExecutionRole
        - Version: "2012-10-17" # Policy Document
          Statement:
            - Effect: Allow
              Action:
                - ses:SendEmail
                - ses:SendRawEmail
              Resource: "*"
      Events:
        APIRoot:
          Type: Api
          Properties:
            Path: /
            Method: POST
            RestApiId: !Ref FormSubmissionApi

  FormSubmissionApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Cors:
        AllowMethods: "'POST'"
        AllowOrigin: "'https://my-domain.com'"
        AllowHeaders: "'x-requested-with'"

Outputs:
  FormSubmissionApi:
    Description: "API Gateway endpoint URL"
    Value: !Sub "https://${FormSubmissionApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
  FormSubmissionFunction:
    Description: "Lambda Function ARN"
    Value: !GetAtt FormSubmissionFunction.Arn

上記のテンプレートは、2つのリソースを定義しています。

  1. FormSubmissionFunction:トリガーされるとメールを送信するラムダ。
  2. FormSubmissionApi:インターネットからパブリックリクエストを受信し、LambdaをトリガーするAPIゲートウェイ。

ラムダコードは、次のindex.jsようなファイルで指定されます。

const aws = require("aws-sdk"); // Library to interact with AWS resources
const ses = new aws.SES({ region: "us-east-1" });

exports.handler = async (eventObject, context, callback) => {
  // Log event data to ease debugging
  console.log(
    "Received event:",
    JSON.stringify(eventObject, context, callback)
  );

  const emailParams = {
    Destination: {
      ToAddresses: ["admin@my-domain.com"],
    },
    Message: {
      Body: {
        Text: {
          Data:
            JSON.stringify(eventObject, context, callback) // TODO: Format your data for email here
        },
      },

      Subject: { Data: "Contact Us Website Form" },
    },
    Source: "admin@my-domain.com",
  };

  // Send the email
  await ses.sendEmail(emailParams).promise();

  // API response
  const response = {
    statusCode: 204,
    headers: {
      "Access-Control-Allow-Headers": "Content-Type",
      "Access-Control-Allow-Origin": "https://my-domain.com",
      "Access-Control-Allow-Methods": "OPTIONS,POST",
    },
    isBase64Encoded: false,
    body: null,
  };

  return response;
};

その中で、Lambdaをトリガーするために使用されたリクエストの本文とヘッダーを含むデータを含むSESを使用してメールを送信します。eventObjectメールの本文は必要に応じてフォーマットできます。

Lambdaのフォームデータを解析するには、以下のライブラリを使用することをお勧めします。

GitHub-francismeynard / lambda-multipart-parser

Lambdaをデプロイするには、script.shファイル(以下に表示)を実行し、画面の指示に従います。

#!/bin/bash

# exit when any command fails
set -e

script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )

sam deploy \
  --template-file ${script_path}/../template.yaml \
  --stack-name serverless-website-form-production \
  --capabilities CAPABILITY_IAM \
  --guided 

結論

受信フォームデータ(またはAPIリクエストからの他のデータ)を受け入れ、データを含む電子メールを送信するために使用できるサーバーレスバックエンドを作成する方法について説明しました。

ただし、このようなものを本番環境にデプロイする前に、ボットがエンドポイントを検出して誤ったデータを送信しないように、 reCaptcha(または同様のもの)を実装することをお勧めします(ボットから電子メールを送信するためのLambda実行時間の料金を請求されたくない) 。

これがお役に立てば幸いです。

このストーリーは、もともとhttps://betterprogramming.pub/create-a-serverless-form-for-a-serverless-website-69b1a62c4eebで公開されました

#serverless #website #api #lambda 

What is GEEK

Buddha Community

サーバーレスWebサイトのサーバーレスフォームを作成する

サーバーレスWebサイトのサーバーレスフォームを作成する

S3 + CloudFrontは、静的Webサイトをホストするためのシンプルで低コストのソリューションを提供します。ただし、HTMLフォームが必要な場合はどうなりますか?この目的のために、単純なサーバーレスバックエンドの実装について説明します。

序章

AWS S3 + Cloudfrontは、スタートアップのランディングページやニュースレターのサインアップページなどの静的なウェブサイトをホストするための低コストでスケーラブルなオプションを提供します。しかし、サーバーなしでフォームを実装するにはどうすればよいでしょうか。

この記事では、AWSのLambdaAPI Gatewayを使用してフォームのサーバーレスバックエンドを調べ、フォームから入力された情報を含むメールをAWSSESを使用して所定のメールに送信するようにトリガーします。

前提条件

Lambdaのコードに飛び込む前に、開発環境とAWSアカウントをセットアップする必要があります。これには以下のポイントが含まれます。

  1. AWSサーバーレスアプリケーションモデル(SAM)ローカル開発ツールは、こちらの手順に従ってインストールされます。
  2. AWS SESは(サンドボックスではなく)本番モードで設定されており、ドメインはこちらの手順に従って確認されています。
  3. この記事の後半で作成されるAPIゲートウェイのエンドポイントにデータを送信するように構成できるHTMLフォームを備えたWebサイトを用意します。

実装

SAMを使用してLambdaとその依存リソースをデプロイします。SAMの詳細については、以下の記事を参照してください。

SAMを使用したAWSLambdaを使用したプライベートサーバーレスRESTAPI

フォルダ構造から始めましょう。アプリケーションソースファイル用のディレクトリ、アプリケーションの展開に使用できるスクリプト用のディレクトリ、およびtemplate.yamlSAMで使用されるようなトップレベルファイル用のディレクトリがあります。

my-serverless-form/
├── cmd/
│   └── deploy.sh
├── src/
|   ├── package.json
│   └── index.js
├── .gitignore 
└── template.yaml

は次のtemplate.yamlようになります。

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
  serverless-form
  SAM project for serverless-form
Parameters:
  LambdaVersion:
    Default: "not-specified"
    Description: "What is the current code version?"
    Type: String

Resources:
  FormSubmissionFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/
      Handler: index.handler
      Runtime: nodejs12.x
      MemorySize: 128
      Timeout: 3
      Environment:
        Variables:
          LAMBDA_VERSION: !Ref LambdaVersion
      Policies:
        - AWSLambdaBasicExecutionRole
        - Version: "2012-10-17" # Policy Document
          Statement:
            - Effect: Allow
              Action:
                - ses:SendEmail
                - ses:SendRawEmail
              Resource: "*"
      Events:
        APIRoot:
          Type: Api
          Properties:
            Path: /
            Method: POST
            RestApiId: !Ref FormSubmissionApi

  FormSubmissionApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Cors:
        AllowMethods: "'POST'"
        AllowOrigin: "'https://my-domain.com'"
        AllowHeaders: "'x-requested-with'"

Outputs:
  FormSubmissionApi:
    Description: "API Gateway endpoint URL"
    Value: !Sub "https://${FormSubmissionApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
  FormSubmissionFunction:
    Description: "Lambda Function ARN"
    Value: !GetAtt FormSubmissionFunction.Arn

上記のテンプレートは、2つのリソースを定義しています。

  1. FormSubmissionFunction:トリガーされるとメールを送信するラムダ。
  2. FormSubmissionApi:インターネットからパブリックリクエストを受信し、LambdaをトリガーするAPIゲートウェイ。

ラムダコードは、次のindex.jsようなファイルで指定されます。

const aws = require("aws-sdk"); // Library to interact with AWS resources
const ses = new aws.SES({ region: "us-east-1" });

exports.handler = async (eventObject, context, callback) => {
  // Log event data to ease debugging
  console.log(
    "Received event:",
    JSON.stringify(eventObject, context, callback)
  );

  const emailParams = {
    Destination: {
      ToAddresses: ["admin@my-domain.com"],
    },
    Message: {
      Body: {
        Text: {
          Data:
            JSON.stringify(eventObject, context, callback) // TODO: Format your data for email here
        },
      },

      Subject: { Data: "Contact Us Website Form" },
    },
    Source: "admin@my-domain.com",
  };

  // Send the email
  await ses.sendEmail(emailParams).promise();

  // API response
  const response = {
    statusCode: 204,
    headers: {
      "Access-Control-Allow-Headers": "Content-Type",
      "Access-Control-Allow-Origin": "https://my-domain.com",
      "Access-Control-Allow-Methods": "OPTIONS,POST",
    },
    isBase64Encoded: false,
    body: null,
  };

  return response;
};

その中で、Lambdaをトリガーするために使用されたリクエストの本文とヘッダーを含むデータを含むSESを使用してメールを送信します。eventObjectメールの本文は必要に応じてフォーマットできます。

Lambdaのフォームデータを解析するには、以下のライブラリを使用することをお勧めします。

GitHub-francismeynard / lambda-multipart-parser

Lambdaをデプロイするには、script.shファイル(以下に表示)を実行し、画面の指示に従います。

#!/bin/bash

# exit when any command fails
set -e

script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )

sam deploy \
  --template-file ${script_path}/../template.yaml \
  --stack-name serverless-website-form-production \
  --capabilities CAPABILITY_IAM \
  --guided 

結論

受信フォームデータ(またはAPIリクエストからの他のデータ)を受け入れ、データを含む電子メールを送信するために使用できるサーバーレスバックエンドを作成する方法について説明しました。

ただし、このようなものを本番環境にデプロイする前に、ボットがエンドポイントを検出して誤ったデータを送信しないように、 reCaptcha(または同様のもの)を実装することをお勧めします(ボットから電子メールを送信するためのLambda実行時間の料金を請求されたくない) 。

これがお役に立てば幸いです。

このストーリーは、もともとhttps://betterprogramming.pub/create-a-serverless-form-for-a-serverless-website-69b1a62c4eebで公開されました

#serverless #website #api #lambda