Laravel

Laravel is a powerful and popular PHP framework that simplifies and accelerates web application development. Its elegant syntax, robust features like Eloquent ORM, Blade templating, and built-in security tools help developers create efficient and scalable apps. With strong community support and extensive documentation, Laravel is an ideal choice for both novice and experienced developers

Laravel Resource Controllers

15 May 2025 | Category:

Resource controllers in Laravel provide a streamlined way to handle CRUD (Create, Read, Update, Delete) operations for a resource, following RESTful conventions. They simplify routing and controller logic by automatically generating standard methods for managing resources like posts, users, or products. This SEO-friendly, plagiarism-free guide explains Laravel resource controllers, how to create and use them, and their benefits. Based on Laravel 11 (as of May 2025), this tutorial is designed for beginners and intermediate developers.


What is a Resource Controller?

A resource controller is a special type of Laravel controller that includes predefined methods for performing CRUD operations on a resource. Instead of manually defining each route and method, Laravel generates a controller with seven standard methods, which align with RESTful routing conventions. This reduces boilerplate code and ensures consistency.

Key Benefits

  • Simplified Routing: One route definition handles all CRUD operations.
  • Consistency: Follows RESTful standards for predictable APIs and web interfaces.
  • Time-Saving: Automatically generates common controller methods.
  • Maintainability: Organizes logic in a structured, reusable way.

Creating a Resource Controller

Laravel’s Artisan command-line tool makes it easy to create a resource controller. To generate a resource controller, run:

php artisan make:controller PostController --resource

This creates a PostController.php file in the app/Http/Controllers/ directory with the following methods:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index()
    {
        // List all resources
    }

    public function create()
    {
        // Show form to create a resource
    }

    public function store(Request $request)
    {
        // Save a new resource
    }

    public function show($id)
    {
        // Display a specific resource
    }

    public function edit($id)
    {
        // Show form to edit a resource
    }

    public function update(Request $request, $id)
    {
        // Update a specific resource
    }

    public function destroy($id)
    {
        // Delete a specific resource
    }
}

Controller for APIs

For API-only resource controllers (excluding create and edit methods, which are for web forms), use the --api flag:

php artisan make:controller Api/PostController --api

This generates a controller with only five methods: index, store, show, update, and destroy.


Resource Routes

To use a resource controller, you define a single resource route in routes/web.php (for web interfaces) or routes/api.php (for APIs). Laravel automatically maps the controller’s methods to standard RESTful routes.

Defining a Resource Route

In routes/web.php:

use App\Http\Controllers\PostController;

Route::resource('posts', PostController::class);

This single line creates seven routes, each mapped to a controller method:

HTTP MethodURIController MethodPurpose
GET/postsindexList all posts
GET/posts/createcreateShow create form (web only)
POST/postsstoreSave new post
GET/posts/{post}showDisplay specific post
GET/posts/{post}/editeditShow edit form (web only)
PUT/PATCH/posts/{post}updateUpdate specific post
DELETE/posts/{post}destroyDelete specific post

For APIs (in routes/api.php), the routes are prefixed with /api/ (e.g., /api/posts) and exclude create and edit.

Viewing Routes

To see all registered routes, run:

php artisan route:list

This displays the URIs, methods, controller actions, and route names (e.g., posts.index, posts.store).


Implementing Resource Controller Logic

Let’s walk through an example of a PostController that manages blog posts, interacting with a Post model and rendering Blade views (for web) or JSON (for APIs).

Example: PostController for Web

Assume a Post model exists with title and content fields.

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index()
    {
        $posts = Post::all();
        return view('posts.index', compact('posts'));
    }

    public function create()
    {
        return view('posts.create');
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'content' => 'required|string',
        ]);

        Post::create($validated);

        return redirect()->route('posts.index')->with('success', 'Post created!');
    }

    public function show(Post $post)
    {
        return view('posts.show', compact('post'));
    }

    public function edit(Post $post)
    {
        return view('posts.edit', compact('post'));
    }

    public function update(Request $request, Post $post)
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'content' => 'required|string',
        ]);

        $post->update($validated);

        return redirect()->route('posts.index')->with('success', 'Post updated!');
    }

    public function destroy(Post $post)
    {
        $post->delete();
        return redirect()->route('posts.index')->with('success', 'Post deleted!');
    }
}

Key Features

  • Route Model Binding: Laravel automatically injects the Post model based on the {post} URI segment (e.g., /posts/1 injects the post with ID 1).
  • Validation: Ensures input meets requirements before saving.
  • Redirects: Uses named routes (e.g., posts.index) for clean navigation.
  • Flash Messages: Adds success messages to the session for user feedback.

Corresponding Blade Views

  • resources/views/posts/index.blade.php: Lists all posts.
  • resources/views/posts/create.blade.php: Form to create a post.
  • resources/views/posts/show.blade.php: Displays a single post.
  • resources/views/posts/edit.blade.php: Form to edit a post.

Example create.blade.php:

<form method="POST" action="{{ route('posts.store') }}">
    @csrf
    <input type="text" name="title" required>
    <textarea name="content" required></textarea>
    <button type="submit">Create Post</button>
</form>

Example: API Resource Controller

For an API, return JSON instead of views:

<?php

namespace App\Http\Controllers\Api;

use App\Models\Post;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    public function index()
    {
        return response()->json(Post::all());
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'content' => 'required|string',
        ]);

        $post = Post::create($validated);
        return response()->json($post, 201);
    }

    public function show(Post $post)
    {
        return response()->json($post);
    }

    public function update(Request $request, Post $post)
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'content' => 'required|string',
        ]);

        $post->update($validated);
        return response()->json($post);
    }

    public function destroy(Post $post)
    {
        $post->delete();
        return response()->json(null, 204);
    }
}
  • JSON Responses: Returns data with appropriate HTTP status codes (e.g., 201 for created, 204 for deleted).
  • No Views: Excludes create and edit methods, as APIs don’t render forms.

Customizing Resource Routes

You can customize resource routes to fit your needs.

Limiting Methods

To include only specific methods, use the only or except options:

Route::resource('posts', PostController::class)->only(['index', 'show']);

This registers only the index and show routes.

Route::resource('posts', PostController::class)->except(['create', 'edit']);

This excludes the create and edit routes.

Customizing Route Names

Override default route names:

Route::resource('posts', PostController::class)->names([
    'index' => 'blog.posts',
    'show' => 'blog.post',
]);

Adding Middleware

Apply middleware to all resource routes:

Route::resource('posts', PostController::class)->middleware('auth');

Or in the controller’s constructor:

public function __construct()
{
    $this->middleware('auth')->except(['index', 'show']);
}

Customizing Parameter Names

By default, the route parameter is the singular resource name (e.g., {post}). Change it:

Route::resource('posts', PostController::class)->parameters([
    'posts' => 'id',
]);

Now, routes use {id} instead of {post}.


Advanced Features

Nested Resource Controllers

For hierarchical resources (e.g., comments on posts), use nested routes:

Route::resource('posts.comments', CommentController::class);

This generates routes like /posts/{post}/comments/{comment}.

API Resource Responses

Use Laravel’s API resources to format JSON responses:

use App\Http\Resources\PostResource;

public function show(Post $post)
{
    return new PostResource($post);
}

Define PostResource in app/Http/Resources/PostResource.php to control the JSON structure.

Generating Model with Controller

Create a model, migration, and resource controller in one command:

php artisan make:model Post -mcr
  • -m: Creates a migration.
  • -c: Creates a controller.
  • -r: Makes it a resource controller.

Best Practices for Resource Controllers

  1. Keep Controllers Thin: Move complex logic to services or repositories.
  2. Use Route Model Binding: Leverage Laravel’s automatic model injection.
  3. Validate Input: Use form requestsapplication logic in a consistent manner.
  4. Follow REST Conventions: Stick to RESTful naming and structure.
  5. Secure Routes: Apply authentication middleware where needed.
  6. Use Named Routes: Reference routes by name (e.g., route('posts.index')).
  7. Organize API Controllers: Place API controllers in App\Http\Controllers\Api.

Conclusion

Resource controllers in Laravel simplify CRUD operations by providing a standardized, RESTful structure for managing resources. With a single route definition, you can handle all standard operations, from listing and creating to updating and deleting. Whether building a web application with Blade views or an API with JSON responses, resource controllers save time and promote clean, maintainable code.

Next Steps:

  • Create a resource controller: php artisan make:controller PostController --resource.
  • Define a resource route in web.php or api.php.
  • Implement CRUD logic and test with a tool like Postman (for APIs).

For deeper insights, explore Laravel’s official documentation or engage with the Laravel community on platforms like X. Start building with resource controllers today!