Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як приймати файли в API: multipart-запит чи пряме завантаження в сховище за підписаним URL?

Варіант 1 - multipart/form-data через сервер API:

POST /api/documents
Content-Type: multipart/form-data; boundary=...

title=Договір
file=<бінарні дані>
$request->validate(['file' => ['required', 'file', 'mimes:pdf', 'max:10240']]);
$path = $request->file('file')->store('documents', 's3');

Просто, валідація й збереження в одному запиті. Але весь файл проходить через сервер застосунку: займає процес PHP на весь час завантаження, обмежений upload_max_filesize/post_max_size і тайм-аутами, а для великих файлів - ще й проксі (client_max_body_size у Nginx).

Варіант 2 - підписаний URL і пряме завантаження в сховище (S3, R2):

  1. клієнт просить дозвіл: POST /api/uploads {"filename": "contract.pdf", "size": 52428800};
  2. сервер перевіряє права й параметри і повертає тимчасовий підписаний URL:
['url' => $url, 'headers' => $headers] = Storage::disk('s3')
    ->temporaryUploadUrl("uploads/{$id}.pdf", now()->plus(minutes: 5));
  1. клієнт завантажує файл напряму в сховище (PUT $url);
  2. клієнт повідомляє API: POST /api/documents {"upload_id": "..."} - сервер перевіряє, що файл справді з'явився, його розмір і тип, і створює запис.

Переваги прямого завантаження: сервер застосунку не тримає з'єднання, немає лімітів PHP, сховище масштабується саме, можна завантажувати частинами (multipart upload S3) з продовженням після збою.

Що обов'язково для безпеки:

  • короткий термін дії URL і фіксований шлях - клієнт не обирає, куди писати;
  • перевірка після завантаження: розмір і тип - не довіряти тому, що клієнт заявив у кроці 1. Підозрілі файли - в карантин чи на антивірусну перевірку;
  • очищення завантажених, але не підтверджених файлів (правило життєвого циклу бакета);
  • приватний бакет і видача файлів теж через підписані URL.

Варіант 3 - base64 у JSON: зручно для дуже малих файлів (аватар-мініатюра), але +33% до розміру й весь файл у пам'яті - для решти погано.

Як обрати: невеликі файли (до кількох мегабайтів) - multipart; великі, багато одночасних завантажень, мобільні клієнти з нестабільною мережею - пряме завантаження.

Докладніше в документації: Laravel: тимчасові URL для завантаження

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання