Howdy,
With 3rd party services being deprecated August 1, 2023 I wanted to reopen this conversation so the community can best understand how we should migrate from 3rd party services in MongoDB Realm, specifically AWS S3 in this case.
The conversation ended with the 3rd party services being extended an additional year and a community member @Adam_Holt kindly sharing an implementation to on how to use AWS S3 successfully and efficiently without 3rd party services.
Given that timeline, I was under the impression that MongoDB would have published some tutorial or made some comments by now as to the best way to use AWS services going forward. Perhaps I missed this in my search.
My question, what is the recommended approach to getObjects and putObjects to AWS S3? Without the 3rd party services and @Adam_Holt’s suggestion, I am only aware of 1 other solution:
Adam’s Solution
Realm function
exports = async function (args) {
const bucket = "my-s3-bucket";
const S3 = require("aws-sdk/clients/s3");
const s3 = new S3({
accessKeyId: context.values.get("awsAccessKeyId"),
secretAccessKey: context.values.get("awsSecretAccessKey"),
region: "ap-southeast-2"
});
const presignedUrl = await s3.getSignedUrlPromise("putObject", {
Bucket: bucket,
Key: args.Key,
ContentType: args.ContentType,
// Duration of the lifetime of the signed url, in milliseconds
Expires: 900000
});
return presignedUrl;
};
Frontend JS code
import { realmUser } from "../../main";
const axios = require("axios");
export default class UploadFile {
async handleFileUpload(file) {
const returnObj = {
s3Path: "",
s3: {},
};
if (file.size > 26214400) {
alert("No files over 25 MB supported");
return false;
}
const key = `files/${file.name}`;
returnObj.s3Path = key;
// AWS S3 Request
const args = {
ContentType: file.type,
Key: key,
};
try {
const presignedUrl = await this.getPresignedS3URL(args);
const options = {
headers: {
"Content-Type": file.type,
},
};
// Saves the file to S3
await axios.put(presignedUrl, file, options);
returnObj.s3.key = key;
} catch (error) {
console.log(error);
}
// Return the data back to a componenet
return returnObj;
}
async getPresignedS3URL(args) {
return new Promise((resolve, reject) => {
realmUser.functions
.uploadTestBuyFile(args)
.then((doc) => {
resolve(doc);
})
.catch((err) => {
reject(err);
});
});
}
}
Legacy Solution (This is remarkably slower than the MongoDB 3rd Party Services)
exports = async function(newId, newPicture, bucket) {
const S3 = require('aws-sdk/clients/s3');
const s3 = new S3({
accessKeyId: context.values.get("AWS_ACCESS_KEY"),
secretAccessKey: context.values.get("AWS_SECRET_ACCESS_KEY_LINKED"),
region: "region",
})
const putResult = await s3.putObject({
Bucket: bucket,
Key: newId,
ContentType: "image/jpeg",
Body: Buffer.from(newPicture, 'base64'),
ContentEncoding: 'base64'
}).promise();
}
Thanks for your help! @henna.s tagging you as you were involved in the prior conversations.