Kritim Yantra
Mar 23, 2025
In this blog, we'll walk through creating a simple CRUD (Create, Read, Update, Delete) API using Laravel 12. We'll also implement proper error handling to ensure that our API is robust and user-friendly. By the end of this tutorial, you'll have a fully functional API with error handling in place.
First, let's create a new Laravel project. Open your terminal and run the following command:
composer create-project laravel/laravel laravel-crud-api
Once the project is created, navigate into the project directory:
cd laravel-crud-api
Next, we need to configure our database. Open the .env
file and update the database credentials:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_crud_api
DB_USERNAME=root
DB_PASSWORD=
Now, run the migrations to create the necessary tables:
php artisan migrate
Install API:
php artisan install:api
Let's create a model and migration for our Product
entity. Run the following command:
php artisan make:model Product -m
This will create a Product
model and a migration file. Open the migration file located in database/migrations
and define the schema:
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('description');
$table->decimal('price', 8, 2);
$table->timestamps();
});
}
Run the migration to create the products
table:
php artisan migrate
Now, let's create a controller to handle our CRUD operations. Run the following command:
php artisan make:controller ProductController --api
This will generate a controller with the basic CRUD methods. Open the ProductController
located in app/Http/Controllers
and implement the methods:
namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Http\Request;
class ProductController extends Controller
{
// Get all products
public function index()
{
$products = Product::all();
return response()->json($products);
}
// Get a single product
public function show($id)
{
$product = Product::find($id);
if (!$product) {
return response()->json(['message' => 'Product not found'], 404);
}
return response()->json($product);
}
// Create a new product
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'description' => 'required|string',
'price' => 'required|numeric',
]);
$product = Product::create($request->all());
return response()->json($product, 201);
}
// Update a product
public function update(Request $request, $id)
{
$product = Product::find($id);
if (!$product) {
return response()->json(['message' => 'Product not found'], 404);
}
$request->validate([
'name' => 'sometimes|string|max:255',
'description' => 'sometimes|string',
'price' => 'sometimes|numeric',
]);
$product->update($request->all());
return response()->json($product);
}
// Delete a product
public function destroy($id)
{
$product = Product::find($id);
if (!$product) {
return response()->json(['message' => 'Product not found'], 404);
}
$product->delete();
return response()->json(['message' => 'Product deleted']);
}
}
Next, let's define the routes for our API. Open the routes/api.php
file and add the following routes:
use App\Http\Controllers\ProductController;
Route::apiResource('products', ProductController::class);
This single line will create all the necessary routes for our CRUD operations.
Now that our API is set up, let's test it using Postman or any other API testing tool.
Send a POST request to /api/products
with the following JSON body:
{
"name": "Laptop",
"description": "A high-end gaming laptop",
"price": 1500.00
}
Send a GET request to /api/products
to retrieve all products.
Send a GET request to /api/products/1
to retrieve a single product.
Send a PUT request to /api/products/1
with the following JSON body:
{
"name": "Updated Laptop",
"price": 1600.00
}
Send a DELETE request to /api/products/1
to delete the product.
Laravel provides a robust error handling mechanism out of the box. However, we can customize the error responses to make them more user-friendly.
Let's modify the ProductController
to return custom error messages. For example, if a product is not found, we can return a 404 error with a custom message:
public function show($id)
{
$product = Product::find($id);
if (!$product) {
return response()->json(['error' => 'Product not found'], 404);
}
return response()->json($product);
}
Laravel automatically handles validation errors and returns a 422 status code with the error messages. However, you can customize the response format by overriding the failedValidation
method in your controller:
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
protected function failedValidation(Validator $validator)
{
throw new HttpResponseException(response()->json([
'error' => 'Validation Error',
'messages' => $validator->errors(),
], 422));
}
In this blog, we've created a simple CRUD API using Laravel 12 and implemented proper error handling to ensure that our API is robust and user-friendly. We've also customized error responses to make them more informative and handled exceptions globally.
By following these steps, you can build a fully functional API with error handling in Laravel. This will help you create more reliable and maintainable applications. Happy coding!
No comments yet. Be the first to comment!
Please log in to post a comment:
Continue with Google