0
0

More than 1 year has passed since last update.

【React】Webアプリケーションの関連付け

Last updated at Posted at 2023-02-12

React axiosとAWS Lambdaを用いて、webページからwebアプリを実行する方法を紹介する。

フロントエンド(React)の作成

  1. axiosをインストールする
    npm install axios --save
    
  2. axiosをimportして、webアプリのURLへPOSTする
    import React from 'react'
    import axios from 'axios'
    
    const Breadcrumbs = () => {
      const [responseData, setResponseData] = React.useState(null)
      const handleSubmission = async (event) => {
        try {
          await axios
            .post(
              'https://*****************************',
              event,
              {
                headers: {
                  'Content-type': 'text/plain',
                },
              },
            )
            .then((res) => {
              setResponseData(res.data)
            })
        } catch (err) {
          console.error(err)
          alert('[ERROR] POSTに失敗しました。')
        }
      }
    }
    
  3. 'https://*****************************'の部分を以下で作成するwebアプリのURLに置き換える。

バックエンド(Lambda関数)の作成

lambdaへPythonコードをアップロードする

  1. 下記のPythonコードを作成する
    CORS(Cross-Origin Resource Sharing)で、どのWebサイトにもOriginを越えるアクセスを許可するため、返却するヘッダーにAccess-Control-Allow-OriginとAccess-Control-Allow-Headersを加えることに注意する。
lambda_function.py
import os
import sys
import time
import json
import base64
import io
import csv
import boto3
import cgi
from requests_toolbelt.multipart import decoder

def lambda_handler(event, context):
    if 'content-type' in event['headers'].keys():
        body = event["body"].encode('utf-8')
        content_type = event['headers']['content-type']
        c_type, c_data = cgi.parse_header(event['headers']['content-type'])
    elif 'Content-Type' in event['headers'].keys():
        body = event["body"].encode('utf-8')
        content_type = event['headers']['Content-Type']
        c_type, c_data = cgi.parse_header(event['headers']['Content-Type'])
    else:
        raise RuntimeError('content-type or Content-Type not found')

    data = json.loads(body)
    
    return {
        'statusCode': 200,
        'headers': {
+            "Access-Control-Allow-Origin": "*",
+            "Access-Control-Allow-Headers": "Content-Type",
        },
        'body': json.dumps('正常にアップロードされました!')
    }
  1. 同じフォルダで下記コマンドを実行して、ローカルにPython moduleをインストールする
pip install -t . --platform manylinux2014_x86_64 --implementation cp --python 3.9 --only-binary=:all: --upgrade requests-toolbelt
  1. zipで圧縮する
  2. 「コード」->「アップロード元」->「.zipファイル」で圧縮したzipファイルを選択して、アップロードする

LambdaにS3とDynamoDBのフルアクセス権限を付与する

  1. 「設定」>「アクセス権限」>実行ロールのロール名のリンクをクリックする
  2. 「許可」>「許可を追加」>「ポリシーをアタッチ」をクリックする
  3. AmazonS3FullAccessとAmazonDynamoDBFullAccessにチェックを入れ、「ポリシーをアタッチ」をクリックする

タイムアウトとメモリの設定を変更する

  1. 「設定」->「一般設定」からメモリを500MBとタイムアウトを15分に変更する

APIgatewayでwebAPIを作成する

  1. トリガーを作成をクリックして、ソースを選択からAPIGatewayをクリックする
  2. Create New APIを選択する
  3. REST APIを選択する
  4. 追加を押す
  5. APIGatewayで作成したAPIの名前をクリックする
  6. 「アクション」->「メゾッドの作成」->でPOSTを選択する
  7. 作成したPOSTをクリックし、統合レスポンスをクリックする
  8. マッピングテンプレートをクリックして、マッピングテンプレートの追加を押す
  9. application/json;charset=UTF-8を追記して、右のチェックを押す
  10. 右側のテンプレートの欄に、$input.json('$')を記入する
    https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
  11. 保存を押す

非同期APIにする場合

  1. [Resources] (リソース) で [POST] を選択し、[Integration Request] (統合リクエスト) を選択する
  2. [HTTP Headers] (HTTP ヘッダー) を展開し、[Add header] (ヘッダーを追加) を選択する
  3. [Name] (名前) に X-Amz-Invocation-Type、 [Mapped from] (マッピング元) に'Event'と入力する
  4. REST API を再デプロイする
  5. 以上

非同期APIではLambdaで受け取るeventの形式が異なり、データサイズが同期が6MBに対して、248KBしかないたため、注意。
あと、なぜかCORSをわざわざAPI gatewayで有効化しないといけない。

補足

Lmabdaのファイルの開き方はいくつかある
パターン1

import csv
import io
import requests

def lambda_handler(event, context):
    csv_file = event['body']
    data = io.StringIO(csv_file)
    reader = csv.DictReader(data)
    for row in reader:
        print(row['column_1'], row['column_2'], row['column_3'], ...)
    return {
        'statusCode': 200,
        'body': 'CSV file processed successfully'
    }

パターン2

import io

def lambda_handler(event, context):
    file_data = event['body']
    decoded_file = file_data.decode('utf-8')
    lines = decoded_file.split('\n')
    for line in lines:
        print(line)
    return {
        'statusCode': 200,
        'body': 'File processed successfully'
    }

参考記事

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