// tutorial

Resource controllers with Route::resource

One artisan command and one route line give you a controller with all 7 conventional CRUD methods already stubbed out and wired to the right verbs and URIs. Here's how it fits together, method by method — and the leaner apiResource version for when there's no browser involved.

php laravel routing 7 min read
  1. Generate the controller

    The --resource flag stubs out all 7 CRUD methods with empty bodies, instead of the single index() you'd get from a plain controller. Add --model to type-hint the methods against an existing Eloquent model.

    bash
    php artisan make:controller ProductController --resource --model=Product

    That creates app/Http/Controllers/ProductController.php with index, create, store, show, edit, update and destroy already declared.

  2. Register the route

    One line in routes/web.php registers all 7 routes at once — the URIs, HTTP verbs and route names all follow REST conventions, so there's nothing left to configure.

    php
    use App\Http\Controllers\ProductController;
    
    Route::resource('products', ProductController::class);

    Confirm what got registered with:

    bash
    php artisan route:list
  3. The 7 methods it expects

    Two of the seven — create and edit — only exist to show HTML forms, which is why they drop out of the API version in the next step.

    Verb URI Method Route name
    GET /products index products.index
    GET /products/create create products.create
    POST /products store products.store
    GET /products/{product} show products.show
    GET /products/{product}/edit edit products.edit
    PUT/PATCH /products/{product} update products.update
    DELETE /products/{product} destroy products.destroy
  4. Fill in a couple of methods

    Because the controller was generated with --model=Product, the methods that take a {product} URI segment already type-hint Product $product — Laravel resolves it from the route via route model binding, no manual lookup needed.

    php
    public function index()
    {
        return Product::latest()->paginate(20);
    }
    
    public function store(Request $request)
    {
        $product = Product::create($request->validate([
            'name' => 'required|string|max:255',
            'price' => 'required|numeric|min:0',
        ]));
    
        return redirect()->route('products.show', $product);
    }
    
    public function show(Product $product)
    {
        return view('products.show', compact('product'));
    }
  5. Building an API instead? Use apiResource

    An API has no HTML forms, so it never needs create or edit. The --api flag generates a controller without those two, and Route::apiResource registers only the remaining 5 routes.

    bash
    php artisan make:controller Api/ProductController --api --model=Product
    php
    use App\Http\Controllers\Api\ProductController;
    
    Route::apiResource('products', ProductController::class);

    That leaves exactly index, store, show, update and destroy — the same verbs and URIs as the table above, minus the two GET routes that used to render forms.