Laravel Routing: All You Need to Know About GET, POST, and Resource Routes
Master Laravel's powerful routing system for handling web requests.
Controllers are the "traffic cops" of your Laravel application. They handle incoming HTTP requests, process business logic, and return responses to users. Instead of putting all your application logic in route files, controllers help you organize code into dedicated classes.
Think of controllers as:
php artisan make:controller UserController
This creates a new controller file at app/Http/Controllers/UserController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
// Controller methods will go here
}
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index()
{
// Display a list of users
}
public function show($id)
{
// Show a single user
}
public function create()
{
// Show user creation form
}
public function store(Request $request)
{
// Store new user
}
}
// routes/web.php
Route::get('/users', [UserController::class, 'index']);
Route::get('/users/{id}', [UserController::class, 'show']);
Route::post('/users', [UserController::class, 'store']);
// Using the same controller for related routes
Route::controller(UserController::class)->group(function () {
Route::get('/users', 'index');
Route::get('/users/create', 'create');
Route::post('/users', 'store');
Route::get('/users/{id}', 'show');
Route::get('/users/{id}/edit', 'edit');
Route::put('/users/{id}', 'update');
Route::delete('/users/{id}', 'destroy');
});
class PageController extends Controller
{
public function home()
{
return view('home');
}
public function about()
{
return view('about', ['team' => Team::all()]);
}
public function contact()
{
return view('contact');
}
}
Create a resource controller with Artisan:
php artisan make:controller PostController --resource
This generates a controller with all resource methods:
class PostController extends Controller
{
public function index() {} // List posts
public function create() {} // Show create form
public function store() {} // Save new post
public function show() {} // Show single post
public function edit() {} // Show edit form
public function update() {} // Update post
public function destroy() {} // Delete post
}
Connect to routes with:
Route::resource('posts', PostController::class);
php artisan make:controller Api/PostController --api
Generates only API-relevant methods (no create/edit):
class PostController extends Controller
{
public function index() {} // GET /posts
public function store() {} // POST /posts
public function show() {} // GET /posts/{id}
public function update() {} // PUT/PATCH /posts/{id}
public function destroy() {} // DELETE /posts/{id}
}
Connect with:
Route::apiResource('posts', PostController::class);
php artisan make:controller WelcomeEmailController --invokable
Creates a controller with single __invoke method:
class WelcomeEmailController extends Controller
{
public function __invoke(User $user)
{
// Send welcome email
Mail::to($user->email)->send(new WelcomeEmail($user));
return response()->json(['message' => 'Welcome email sent!']);
}
}
Route to it with:
Route::post('/welcome-email/{user}', WelcomeEmailController::class);
public function index()
{
$users = User::with('posts')
->orderBy('created_at', 'desc')
->paginate(10);
return view('users.index', compact('users'));
}
public function show(User $user) // Route Model Binding
{
return view('users.show', compact('user'));
}
public function create()
{
return view('users.create');
}
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8|confirmed',
]);
$user = User::create($validated);
return redirect()->route('users.show', $user)
->with('success', 'User created successfully!');
}
public function edit(User $user)
{
return view('users.edit', compact('user'));
}
public function update(Request $request, User $user)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email,' . $user->id,
]);
$user->update($validated);
return redirect()->route('users.show', $user)
->with('success', 'User updated successfully!');
}
public function destroy(User $user)
{
$user->delete();
return redirect()->route('users.index')
->with('success', 'User deleted successfully!');
}
use Illuminate\Http\Request;
public function store(Request $request)
{
// Get all input data
$data = $request->all();
// Get specific input
$name = $request->input('name');
$email = $request->email; // Alternative syntax
// Get only specific fields
$data = $request->only(['name', 'email']);
$data = $request->except(['password', 'token']);
// Check if input exists
if ($request->has('newsletter')) {
// Subscribe to newsletter
}
}
Create custom request classes for complex validation:
php artisan make:request StoreUserRequest
// app/Http/Requests/StoreUserRequest.php
class StoreUserRequest extends FormRequest
{
public function authorize()
{
return true; // Set authorization logic
}
public function rules()
{
return [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8|confirmed',
];
}
public function messages()
{
return [
'name.required' => 'The name field is required.',
'email.unique' => 'This email is already taken.',
];
}
}
Use in controller:
public function store(StoreUserRequest $request)
{
// Validation already passed!
$user = User::create($request->validated());
return redirect()->route('users.show', $user);
}
public function show(User $user)
{
return view('users.show', [
'user' => $user,
'posts' => $user->posts()->paginate(5)
]);
}
public function apiIndex()
{
$users = User::all();
return response()->json([
'data' => $users,
'count' => $users->count()
]);
}
public function store(Request $request)
{
// After successful operation
return redirect('/users');
// With route name
return redirect()->route('users.index');
// With flash data
return redirect()->route('users.index')
->with('success', 'User created!');
// Back to previous page
return back()->withInput();
}
public function download()
{
return response()->download($pathToFile);
}
public function pdf()
{
return response()->streamDownload(function () {
// Generate PDF content
}, 'document.pdf');
}
class UserController extends Controller
{
public function __construct()
{
// Apply to all methods
$this->middleware('auth');
// Apply to specific methods
$this->middleware('log')->only('index', 'show');
$this->middleware('admin')->except('index', 'show');
// Apply to multiple methods
$this->middleware('throttle:60,1')->only('store', 'update');
}
}
Route::middleware(['auth', 'verified'])->group(function () {
Route::resource('users', UserController::class);
});
Laravel automatically resolves dependencies through type-hinting:
use App\Services\UserService;
use App\Repositories\PostRepository;
use Illuminate\Http\Request;
class UserController extends Controller
{
protected $userService;
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
public function store(Request $request, PostRepository $postRepo)
{
// Laravel automatically injects these dependencies
$user = $this->userService->createUser($request->all());
$posts = $postRepo->getUserPosts($user->id);
return view('users.show', compact('user', 'posts'));
}
}
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use App\Http\Requests\StorePostRequest;
use App\Http\Requests\UpdatePostRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class PostController extends Controller
{
public function __construct()
{
$this->middleware('auth')->except(['index', 'show']);
$this->middleware('can:update,post')->only(['edit', 'update']);
$this->middleware('can:delete,post')->only('destroy');
}
public function index()
{
$posts = Post::with('user', 'categories')
->published()
->latest()
->paginate(10);
return view('posts.index', compact('posts'));
}
public function show(Post $post)
{
// Increment views
$post->increment('views');
return view('posts.show', compact('post'));
}
public function create()
{
return view('posts.create');
}
public function store(StorePostRequest $request)
{
$post = Post::create($request->validated());
// Handle image upload
if ($request->hasFile('image')) {
$path = $request->file('image')->store('posts', 'public');
$post->update(['image_path' => $path]);
}
// Sync categories
$post->categories()->sync($request->categories);
return redirect()->route('posts.show', $post)
->with('success', 'Post created successfully!');
}
public function edit(Post $post)
{
return view('posts.edit', compact('post'));
}
public function update(UpdatePostRequest $request, Post $post)
{
$post->update($request->validated());
return redirect()->route('posts.show', $post)
->with('success', 'Post updated successfully!');
}
public function destroy(Post $post)
{
// Delete associated image
if ($post->image_path) {
Storage::disk('public')->delete($post->image_path);
}
$post->delete();
return redirect()->route('posts.index')
->with('success', 'Post deleted successfully!');
}
}
// ❌ DON'T: Put all logic in controller
public function store(Request $request)
{
// Validation
$validated = $request->validate([...]);
// Business logic
if ($request->has('discount')) {
// Complex pricing logic...
}
// Database operations
$order = Order::create([...]);
// Email sending
Mail::to($user)->send(...);
// File handling
if ($request->hasFile('file')) {
// File processing...
}
}
// ✅ DO: Delegate to services
public function store(StoreOrderRequest $request)
{
$order = $this->orderService->createOrder($request->validated());
return redirect()->route('orders.show', $order);
}
1. What is a controller in Laravel?
Controllers handle HTTP requests, contain business logic, and return responses. They act as intermediaries between models and views.
2. How do you create a controller?
Use php artisan make:controller ControllerName. Add --resource for CRUD methods or --api for API controllers.
3. What are resource controllers?
Resource controllers provide built-in methods for CRUD operations: index, create, store, show, edit, update, destroy.
4. What is single action controller?
A controller with only one __invoke method, perfect for dedicated actions like sending emails or processing payments.
5. How do you apply middleware to controllers?
Either in the controller constructor using $this->middleware() or in route definitions using Route::middleware()->group().
6. What is dependency injection in controllers?
Laravel automatically resolves type-hinted dependencies in controller constructors and methods, making services available without manual instantiation.
# Basic controller
php artisan make:controller UserController
# Resource controller
php artisan make:controller PostController --resource
# API resource controller
php artisan make:controller Api/PostController --api
# Single action controller
php artisan make:controller WelcomeEmailController --invokable
# Controller with model
php artisan make:controller CategoryController --model=Category
# Form request
php artisan make:request StoreUserRequest
Now you can create organized, efficient controllers for any Laravel application! In our next post, we'll explore Laravel Blade Templating: Master the Basics of Laravel's View Engine to learn how to create beautiful, dynamic views.