Работа с S3 и облачными хранилищами в TypeScript
Современные веб-приложения всё чаще используют облачные объектные хранилища для хранения файлов, изображений, резервных копий и статического контента. Amazon S3 (Simple Storage Service) является де-факто стандартом в этой области, а его API поддерживается большинством облачных провайдеров и локальных решений, таких как MinIO, DigitalOcean Spaces или Yandex Object Storage. В этой статье мы рассмотрим, как работать с S3-совместимыми хранилищами в TypeScript, используя официальный AWS SDK и альтернативные библиотеки.
Выбор библиотеки для работы с S3 в TypeScript
Для взаимодействия с S3 из TypeScript существует несколько популярных решений:
- @aws-sdk/client-s3 — официальный SDK от Amazon, написанный на TypeScript, модульный и современный.
- aws-sdk — классическая версия SDK (v2), которая всё ещё поддерживается, но рекомендуется переходить на v3.
- minio — клиентская библиотека для MinIO и любых S3-совместимых хранилищ, простая и лёгкая.
- s3-client — минималистичная обёртка над fetch API для работы с S3.
Мы сосредоточимся на @aws-sdk/client-s3 как на наиболее актуальном и мощном инструменте, а также покажем примеры с minio для случаев, когда нужна лёгкая альтернатива.
Установка и настройка
Установите необходимые пакеты через npm:
npm install @aws-sdk/client-s3 @aws-sdk/lib-storage
npm install --save-dev @types/node typescript
Для работы с MinIO:
npm install minio
Теперь создадим базовый клиент S3. Убедитесь, что у вас есть переменные окружения или конфигурация с ключами доступа.
Пример 1: Инициализация клиента S3
import { S3Client } from "@aws-sdk/client-s3";
const s3Client = new S3Client({
region: process.env.AWS_REGION || "us-east-1",
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
// Для MinIO или локального S3 укажите endpoint:
// endpoint: "http://localhost:9000",
// forcePathStyle: true,
});
export default s3Client;
Обратите внимание на параметр forcePathStyle — он обязателен для MinIO и некоторых других не-AWS хранилищ.
Пример 2: Загрузка файла в S3
Для загрузки файла используем команду PutObjectCommand:
import { PutObjectCommand } from "@aws-sdk/client-s3";
import s3Client from "./s3Client";
async function uploadFile(bucket: string, key: string, body: Buffer | string) {
const command = new PutObjectCommand({
Bucket: bucket,
Key: key,
Body: body,
ContentType: "application/octet-stream",
});
try {
const response = await s3Client.send(command);
console.log("Файл загружен:", response.$metadata.httpStatusCode);
return response;
} catch (error) {
console.error("Ошибка загрузки:", error);
throw error;
}
}
// Использование:
await uploadFile("my-bucket", "uploads/image.png", bufferFromFile);
Для потоковой загрузки больших файлов используйте @aws-sdk/lib-storage:
import { Upload } from "@aws-sdk/lib-storage";
import { Readable } from "stream";
const upload = new Upload({
client: s3Client,
params: {
Bucket: "my-bucket",
Key: "large-file.zip",
Body: Readable.from(fileStream),
},
});
upload.on("httpUploadProgress", (progress) => {
console.log(`Загружено: ${progress.loaded} из ${progress.total}`);
});
await upload.done();
Пример 3: Скачивание файла
Для получения объекта из хранилища используем GetObjectCommand:
import { GetObjectCommand } from "@aws-sdk/client-s3";
import s3Client from "./s3Client";
async function downloadFile(bucket: string, key: string): Promise<Buffer> {
const command = new GetObjectCommand({
Bucket: bucket,
Key: key,
});
const response = await s3Client.send(command);
const stream = response.Body as Readable;
return new Promise((resolve, reject) => {
const chunks: Buffer[] = [];
stream.on("data", (chunk) => chunks.push(chunk));
stream.on("end", () => resolve(Buffer.concat(chunks)));
stream.on("error", reject);
});
}
// Пример использования:
const fileBuffer = await downloadFile("my-bucket", "documents/report.pdf"); Также в библиотеке
Авторизация и аутентификация в Go (Golang): JWT, OAuth2 и сессии
Отправка email на PHP: Полное руководство по библиотеке PHPMailer
Конфигурация приложений PHP: библиотеки и инструменты для гибкой настройки
ORM для TypeScript: сравнение TypeORM, Prisma и MikroORM