Возможно, у нас есть файлы, созданные пользователями, загруженные через форму. Или, может быть, мы создаем файлы для загрузки нашими пользователями. В любом случае нам нужно место для хранения этих файлов. Обычно мы храним эти файлы на нашем локальном диске. Это нормально работает, если у нас есть только один сервер. Или если нам удастся поделиться диском с несколькими серверами. Гораздо более простое решение - использовать облако для хранения нашего содержимого.

Для хранения файлов я лично выбрал AWS S3. В этом небольшом посте я покажу, как мы можем легко загружать файлы в S3 из нашего приложения Node.

Для загрузки файлов в S3 нам понадобится пакет aws-sdk от npm:

npm install -S aws-sdk

Теперь мы можем начать писать наш код:

Код написан на TypeScript, но если вы знакомы с JavaScript и новейшими функциями ES, это не составит труда понять.

В этом примере кода мы собираемся загрузить файл, который уже находится на нашем диске. Вверху мы импортировали необходимые модули для этой задачи. Нам нужен модуль fs для чтения файла, aws-sdk для загрузки в S3. Затем мы определили наши учетные данные AWS и корзину, в которую мы будем загружать файл. В идеале мы должны считывать эти значения из переменных среды или файла конфигурации.

Затем мы инициализируем клиент S3 с учетными данными AWS. Функция uploadToS3 выполняет фактическую загрузку файла. Внутри него мы сначала создаем читаемый поток из имени файла. Для краткости я пропустил проверку ошибок. Затем мы создаем параметры, которые необходимо передать методу upload на клиенте S3. Сюда входит имя сегмента, уникальный ключ для имени файла и содержимое файла.

В качестве содержимого файла мы передаем читаемый поток. Обратите внимание, что мы могли прочитать файл синхронно и передать все содержимое файла прямо сюда. Это сработало бы для небольших файлов. Но если вы пытаетесь загрузить большой файл, потоковая загрузка намного эффективнее.

Мы вызываем метод upload с переданными параметрами. В этом случае мы обертываем API на основе обратного вызова, чтобы вернуть обещание. Когда операция завершается, внутри обратного вызова мы обрабатываем любые ошибки, а затем разрешаем обещание с ответом, возвращенным от S3. К этому времени загрузка файла либо завершилась, либо произошла ошибка. Нам больше не нужен файловый поток. Итак, мы уничтожаем читаемый поток.

Файл uploadToS3() возвращает объект обещания, который разрешается с данными, возвращенными из S3, или отклоняется с любыми ошибками.

В нашем примере мы загрузили файл с нашего локального диска, который уже был там. Мы также можем адаптировать этот пример кода для непосредственного приема читаемого потока и перенаправления загруженных файлов на S3 без предварительного сохранения их на диск. Но я бы оставил это читателю в качестве упражнения.