Back to Course |
How to Build Laravel 11 API From Scratch

Finishing CRUD: Update, Delete and Resource Controller

In this lesson, we will finalize our resource Controller with two missing methods: update and delete the category.


First, the update method. The method for the Route is PUT, and in the Controller, the method is usually update.

routes/api.php:

Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
 
Route::get('categories', [\App\Http\Controllers\Api\CategoryController::class, 'index']);
Route::get('categories/{category}', [\App\Http\Controllers\Api\CategoryController::class, 'show']);
Route::post('categories', [\App\Http\Controllers\Api\CategoryController::class, 'store']);
Route::put('categories/{category}', [\App\Http\Controllers\Api\CategoryController::class, 'update']);
 
Route::get('products', [\App\Http\Controllers\Api\ProductController::class, 'index']);

app/Http/Controllers/Api/CategoryController.php:

class CategoryController extends Controller
{
// ...
 
public function update(Category $category, StoreCategoryRequest $request)
{
$category->update($request->all());
 
return new CategoryResource($category);
}
}

In the Controller, we use a Route Model Binding to find a record and the same Form Request for validation. In the update method, we update the category and return the updated category.

In the client, we can send a PUT request to the /api/categories endpoint and pass the ID of an existing category.

In the result, we see the updated data.


Now, let's do the delete.

route/api.php:

Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
 
Route::get('categories', [\App\Http\Controllers\Api\CategoryController::class, 'index']);
Route::get('categories/{category}', [\App\Http\Controllers\Api\CategoryController::class, 'show']);
Route::post('categories', [\App\Http\Controllers\Api\CategoryController::class, 'store']);
Route::put('categories/{category}', [\App\Http\Controllers\Api\CategoryController::class, 'update']);
Route::delete('categories/{category}', [\App\Http\Controllers\Api\CategoryController::class, 'destroy']);
 
Route::get('products', [\App\Http\Controllers\Api\ProductController::class, 'index']);

In the Controller, after the record is deleted, what to return? We don't have the record anymore. We can return a 204 no content status in such cases.

app/Http/Controllers/Api/CategoryController.php:

use Symfony\Component\HttpFoundation\Response;
 
class CategoryController extends Controller
{
// ...
 
public function destroy(Category $category)
{
$category->delete();
 
return response(null, Response::HTTP_NO_CONTENT);
}
}

Or, we can use a shorter syntax.

app/Http/Controllers/Api/CategoryController.php:

class CategoryController extends Controller
{
// ...
 
public function destroy(Category $category)
{
$category->delete();
 
return response(null, Response::HTTP_NO_CONTENT);
return response()->noContent();
}
}

Let's launch the endpoint from the client.

As you can see, there is no content in the preview, and the status is 204 no content.


Finally, let's wrap all the Routes into a resource. In a typical Laravel project for the CRUD Controllers, you would make a resource Route.

Route::resource('categories', \App\Http\Controllers\Api\CategoryController::class);

But with API, there is a specific method called apiResource. This method adds five Routes instead of seven. We don't need the create and edit methods when working with the API.

routes/api.php:

Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
 
Route::get('categories', [\App\Http\Controllers\Api\CategoryController::class, 'index']);
Route::get('categories/{category}', [\App\Http\Controllers\Api\CategoryController::class, 'show']);
Route::post('categories', [\App\Http\Controllers\Api\CategoryController::class, 'store']);
Route::put('categories/{category}', [\App\Http\Controllers\Api\CategoryController::class, 'update']);
Route::delete('categories/{category}', [\App\Http\Controllers\Api\CategoryController::class, 'destroy']);
Route::apiResource('categories', \App\Http\Controllers\Api\CategoryController::class);
 
Route::get('products', [\App\Http\Controllers\Api\ProductController::class, 'index']);