Controllers & the Artisan make:controller Command
Controllers group related request handling logic into a single class. As applications grow, keeping all logic in route closures becomes unmaintainable — you can't reuse code, test it independently, or organize it by domain. Controllers are the C in MVC: they receive requests, orchestrate the business logic (often by calling services or models), and return responses. Every serious Laravel application uses controllers.
Creating Controllers
// php artisan make:controller PostController
class PostController extends Controller
{
public function index(): View
{
$posts = Post::with('user')
->published()
->latest()
->paginate(10);
return view('posts.index', compact('posts'));
}
public function show(Post $post): View
{
$post->load('comments.user', 'tags');
return view('posts.show', compact('post'));
}
public function store(StorePostRequest $request): RedirectResponse
{
$post = auth()->user()->posts()->create(
$request->validated()
);
return redirect()
->route('posts.show', $post)
->with('success', 'Post created successfully!');
}
public function update(UpdatePostRequest $request, Post $post): RedirectResponse
{
$this->authorize('update', $post);
$post->update($request->validated());
return redirect()->route('posts.show', $post);
}
public function destroy(Post $post): RedirectResponse
{
$this->authorize('delete', $post);
$post->delete();
return redirect()->route('posts.index');
}
}Controller Best Practices
- Keep controllers thin — they should orchestrate, not implement business logic. Move complex operations to Service classes or Action classes that controllers call
- Use Form Requests (php artisan make:request StorePostRequest) for validation — keeps controllers clean and makes validation rules reusable and testable
- Return typed responses: View, JsonResponse, RedirectResponse. Explicit types make the code self-documenting and help IDEs catch errors
- Use $this->authorize() to check permissions via Policies. Never put authorization logic in blade — always enforce it in the controller
- One controller per resource (PostController, UserController, CommentController). Avoid generic controllers that handle multiple unrelated resources — they grow into unmaintainable monsters
Tip
Tip
Practice Controllers the Artisan makecontroller Command in small, isolated examples before integrating into larger projects. Breaking concepts into small experiments builds genuine understanding faster than reading alone.
Route::resource generates all 7 CRUD routes with one line
Practice Task
Note
Practice Task — (1) Write a working example of Controllers the Artisan makecontroller Command from scratch without looking at notes. (2) Modify it to handle an edge case (empty input, null value, or error state). (3) Share your solution in the Priygop community for feedback.
Quick Quiz
Common Mistake
Warning
A common mistake with Controllers the Artisan makecontroller Command is skipping edge case testing — empty inputs, null values, and unexpected data types. Always validate boundary conditions to write robust, production-ready laravel code.
Key Takeaways
- Controllers group related request handling logic into a single class.
- Keep controllers thin — they should orchestrate, not implement business logic. Move complex operations to Service classes or Action classes that controllers call
- Use Form Requests (php artisan make:request StorePostRequest) for validation — keeps controllers clean and makes validation rules reusable and testable
- Return typed responses: View, JsonResponse, RedirectResponse. Explicit types make the code self-documenting and help IDEs catch errors