File Uploads in Laravel 12 API (With Validation & Storage)
"Users want to upload images, resumes, documents — and your API needs to handle it like a pro!"
Whether you're building a job portal, a photo-sharing app, or a document manager, file uploads are a must-have feature. In Laravel 12, uploading files via an API is simple, secure, and scalable — if done the right way.
In this step-by-step guide, you'll learn how to:
- 📦 Upload files via API
- ✅ Validate file types and sizes
- 💾 Store files properly using Laravel’s storage system
- 🔒 Secure your upload endpoints
Let’s dive in!
🧠 How File Uploads Work in an API
Here’s what happens behind the scenes:
- User uploads a file (image, PDF, etc.) from frontend or Postman
- The API receives it as a
multipart/form-datarequest - Laravel validates and stores it
- Laravel returns the URL or path to the stored file
🛠️ Step 1: Create a Model & Migration
Let’s build a Document model to store uploaded files.
php artisan make:model Document -m
Edit the migration file:
Schema::create('documents', function (Blueprint $table) {
$table->id();
$table->string('name'); // original filename
$table->string('path'); // storage path
$table->timestamps();
});
Run the migration:
php artisan migrate
👨💻 Step 2: Create a Controller
php artisan make:controller API/DocumentController
In DocumentController.php:
use Illuminate\Http\Request;
use App\Models\Document;
use Illuminate\Support\Facades\Storage;
class DocumentController extends Controller
{
public function store(Request $request)
{
// ✅ Validate the file
$request->validate([
'file' => 'required|file|mimes:jpg,jpeg,png,pdf|max:2048' // 2MB max
]);
// 🧾 Store file in 'uploads' disk
$path = $request->file('file')->store('uploads', 'public');
// 📦 Save info to DB
$document = Document::create([
'name' => $request->file('file')->getClientOriginalName(),
'path' => $path
]);
// ✅ Return success with path
return response()->json([
'message' => 'File uploaded successfully!',
'file_url' => asset('storage/' . $path)
]);
}
}
📁 Step 3: Define the Route
In routes/api.php:
use App\Http\Controllers\API\DocumentController;
Route::post('/upload', [DocumentController::class, 'store']);
🧪 Step 4: Test in Postman or Thunder Client
Set the request type to POST and URL to:
http://localhost:8000/api/upload
Under Body tab:
- Choose form-data
- Key:
file - Type:
File - Choose an image or PDF to upload
You should receive:
{
"message": "File uploaded successfully!",
"file_url": "http://localhost:8000/storage/uploads/your-file.jpg"
}
🛡️ Step 5: Secure Uploads (Optional But Important)
To secure uploads for authenticated users:
Route::middleware('auth:sanctum')->post('/upload', [DocumentController::class, 'store']);
Make sure your API uses Laravel Sanctum for auth.
🔁 Bonus: Accept Multiple Files
Want to upload multiple files at once?
Update validation and loop through files:
$request->validate([
'files.*' => 'required|file|mimes:jpg,png,pdf|max:2048'
]);
$paths = [];
foreach ($request->file('files') as $file) {
$paths[] = $file->store('uploads', 'public');
}
📦 Storage Setup
Make sure the public disk is linked:
php artisan storage:link
This allows files stored in /storage/app/public to be publicly accessible via /storage.
🧠 Summary: What You Learned
- ✅ How to handle file uploads via API
- 🔒 Validating file types, size, and structure
- 💾 Using Laravel's
Storagefacade for saving files - 📂 Returning proper file URLs
- 🔐 Securing uploads with middleware
Projects related to this guide
Use the concepts from this article in practical source-code projects.
Flask Authentication System (Free Version) - Kritim Yantra
🛠 Features✔ Google & GitHub Authentication✔ User Registration & Login✔ Profile/Dashboard Access✔ Secure...
Python Flask Blog Project with Admin Panel
Are you ready to launch a powerful, modern, and fully customizable blog? Look no further! Introducing the Flask-...
Laravel 12 + ReactJS Starter Kit: Add Multi-Language Support (Arabic, English, Spanish) with Blog CRUD
🚀 Installation & Setup Download & Extract Get the ZIP from kritimyantra.com and extract it. Includes pr...
Comments
No comments yet. Be the first to comment.
Sign in to join the discussion.