How to receive data sent by file with API Gateway (REST API) + Lambda (node.js v16)

How to receive data sent by file with API Gateway (REST API) + Lambda (node.js v16)

curl

Send a local sample.json file with curl.

sample.json

{
  "name": "takahashi",
  "age": 20
}

Only one file will be used in this case.

curl -X POST -F file1=@sample.json https://xxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/

API Gateway

Configure the API Gateway settings, creating an API with the POST method of the REST API.

API Gateway(REST API)+Lambda(node.js v16)でファイル送信したデータを受け取る方法

Set the binary media type to “multipart/form-data”.

API Gateway(REST API)+Lambda(node.js v16)でファイル送信したデータを受け取る方法

API Gateway(REST API)+Lambda(node.js v16)でファイル送信したデータを受け取る方法

API Gateway(REST API)+Lambda(node.js v16)でファイル送信したデータを受け取る方法

Uncheck Lambda proxy integration in the integration request settings.

Set the following two HTTP headers

  • ‘*/*’
  • ‘method.request.header.Content-Type’

Under Mapping Templates, select “No template defined (recommended)” and click “Add Mapping Template”.

Enter “multipart/form-data” and save it. In Generate Template, select “Method request pass-through” and save it.

Now if you deploy, curl will issue a URL to execute.

API Gateway(REST API)+Lambda(node.js v16)でファイル送信したデータを受け取る方法

Lambda

Next, Lambda (node.js v16) receives the json data.

Use the parse-multipart-data module.

npm i parse-multipart-data

The following data is passed to Lambda.

event["body-json"].toString()The following data is passed to Lambda.
↓
[
  {
    filename: 'sample.json', // local filename
    type: 'application/octet-stream',
    name: 'file1', // File name specified by curl
    data: 
  }
]

event.params.header['content-type']
↓
multipart/form-data; boundary=------------------------5be85402ae18ca66

From this value (event.params.header[‘content-type’]), the boundary is first obtained.

const boundary = multipart.getBoundary(event.params.header['content-type'])
console.log(boundary) // ------------------------5be85402ae18ca66

multipart.parse. Specify boundary as the second argument.

const part = multipart.parse(Buffer.from(datas, "base64") ,boundary)
↓
[
  {
    filename: 'sample.json',
    type: 'application/octet-stream',
    name: 'file1',
    data: 
  }
]

The reason it comes as an array is that curl can send multiple files.

Now, if we convert part.data from Buffer to String, we can handle the local sample.json.

Lambda source.

import multipart from 'parse-multipart-data'
import { StringDecoder } from "string_decoder"
const decoder = new StringDecoder("utf-8")
export async function handler(event, context) {
  const boundary = multipart.getBoundary(event.params.header['content-type'])
  const part = multipart.parse(Buffer.from(event["body-json"].toString(), "base64") ,boundary)
  const ret = decoder.write(part[0].data) // buffer→string
  return {
    statusCode: 200,
    body: `${ret}`
  }
}

Test

Finally, test with curl.

API Gateway(REST API)+Lambda(node.js v16)でファイル送信したデータを受け取る方法

You can confirm that the contents of sample.json are returned.

Reference Site

multiplepart/from-data: AWS API Gateway + Lambda
How to handle binary & string data types using Python
[Lambda] API Gateway + Lambda 를 이용하여 S3 에 이미지 업로드
IAM 역할 만들기 두 개의 Policy 를 붙여주자. - AWSLambdaBasicExecutionRole: AWS CloudWatch > Log Groups 에 Lambda 로그를 남길 수 있는 권한 - Amaz...
parse-multipart-data
A javascript/nodejs multipart/form-data parser which operates on raw data.. Latest version: 1.5.0, last published: a yea...

コメント

タイトルとURLをコピーしました