#node.js #amazon-web-services #amazon-s3
Вопрос:
В лямбда-функции на основе Node.js12.x я пытаюсь
- Загрузить объект из S3
- Загрузите файл из Интернета, если объект не существует в S3
- Передайте загруженные данные независимо от того, как они поступили в несколько потоков записи
Я попытался следовать
var request = require('request');
const readStream = ({ Bucket, Key }) => {
s3.getObjectMetadata({ Bucket, Key })
.promise().then(() => {
return s3.getObject().createReadStream();
})
.catch(error => {
if (error.statusCode === 404) {
return request.get('http://example.com/' Key);
}
});
};
readStream({ ... })
.pipe(sharp().resize(w, h).toFormat('png'))
.pipe(writeStream);
Выше работает, если объект доступен в s3, но блок catch не работает.
Мне нужно await
или нужно обещание request.get
?
Я также пытался следовать за ним, но безуспешно
http.get('http://example.com/' Key, function(response) {
return response;
});
Ответ №1:
Сначала нам нужно создать обещание, которое проверяет, существует ли объект в корзине
const isObjectExists = (params) => {
return s3.headObject(params)
.promise()
.then(
() => true,
(error) => {
if (err.statusCode === 404) {
return false;
}
throw error;
}
)}
const awsParams = { Bucket: ..., Key: s3ObjectKey };
const exists = await isObjectExists(awsParams);
Затем нам нужно создать поток чтения либо из s3, либо из веб-URL.
Используя устаревший request
пакет, так как я не могу заставить вещи работать с помощью http
.
let readStream = null;
if (exists) {
readStream = s3.getObject(awsParams).createReadStream();
} else {
readStream = request.get('http://example.com/' s3ObjectKey);
}
Передайте только что созданное readStream
в процесс и, наконец, в поток загрузки
const pass = new PassThrough();
readStream.
.pipe(sharp().resize(w, h).toFormat('png'))
.pipe(s3.upload({
Body: pass,
Bucket,
ContentType: 'image/png',
s3ObjectKey '-resized'
}).promise());
const uploadedData = await pass;
Добавьте несколько предварительных условий
import awS3 from 'aws-sdk/clients/s3';
import { PassThrough } from 'stream'
import * as request from 'request';
const s3 = new awS3({signatureVersion: 'v4'});