Image File Upload To Aws Lambda Using AWS Api Gateway
I am trying to create a lambda function which accepts an image as multipart/form-data, do some processing on the image and upload it to s3 and also returns reponse to the client. But i am stuck at the very first part of uploading the image to aws lambda using API gateway. I tried to do this in NodeJS as shown below:
exports.handler = async (event, context, callback) => {
var buf = Buffer.from(event.body.replace(/^data:image\/\w+;base64,/, ""),"base64");
var data = {
Bucket: "bucket-name",
Key: "abc.jpg",
Body: buf,
ContentType: 'image/jpg',
ACL: 'public-read'
};
data = await s3.upload(data).promise();
return {
statusCode: 200,
body: JSON.stringify(buf),
};
I am getting the following response in Postman by making POST request to the api:
{
"ETag": "\"b0e5b18d38904f109e0aef0b29e132be\"",
"Location": "https://bucket-name.s3.us-east-2.amazonaws.com/abc.jpg",
"key": "abc.jpg",
"Key": "abc.jpg",
"Bucket": "bucket-name"
}
But when i try to view the uploaded image in my browser using public url in the returned in the above response, i am getting empty image.
Can somebody point me the mistake here or suggest some better approach. Thank you.
Answer
As suggested by Ashan, you can go with best practice of uploading images via browser.
If the image size is not that large, here is working example of uploading image to S3 via ApiGateway/Lambda Proxy Integration.
Lambda Function Code -
exports.handler = (event, context, callback) => {
let encodedImage = JSON.parse(event.body).user_avatar;
let decodedImage = Buffer.from(encodedImage, 'base64');
var filePath = "avatars/" + event.queryStringParameters.username + ".png"
var params = {
"Body": decodedImage,
"Bucket": "bucketName",
"Key": filePath,
"ContentType " : "mime/png"
};
s3.upload(params, function (err, data) {
if (err) {
callback(err, null);
} else {
let response = {
"statusCode": 200,
"body": JSON.stringify(data),
"isBase64Encoded": false
};
callback(null, response);
}
});
};
Serverless.yml
service: aws-api-lambda-s3-image-upload
frameworkVersion: ">=1.1.0 <2.0.0"
provider:
name: aws
runtime: nodejs8.10
iamRoleStatements:
- Effect: "Allow"
Action:
- "s3:ListBucket"
Resource: "arn:aws:s3:::bucketName"
- Effect: "Allow"
Action:
- "s3:PutObject"
Resource: "arn:aws:s3:::bucketName/*"
functions:
index:
handler: handler.handler
events:
- http: POST handler
Json Payload Should be -
{
"user_avatar" : "<<base64 encoded image>>"
}
Related Questions
- → Maximum call stack exceeded when instantiating class inside of a module
- → Browserify api: how to pass advanced option to script
- → Node.js Passing object from server.js to external modules?
- → gulp-rename makes copies, but does not replace
- → requiring RX.js in node.js
- → Remove an ObjectId from an array of objectId
- → Can not connect to Redis
- → React: How to publish page on server using React-starter-kit
- → Express - better pattern for passing data between middleware functions
- → Can't get plotly + node.js to stream data coming through POST requests
- → IsGenerator implementation
- → Async/Await not waiting
- → (Socket.io on nodejs) Updating div with mysql data stops without showing error