How to Create REST API in Laravel - Simple CRUD Example
Build a Secure Laravel REST API CRUD, In this tutorial, I'll walk you through how to Building RESTful APIs with Laravel. creating a simple CRUD (Create, Read, Update, Delete) REST API in Laravel Step by Step.

In today's web development landscape, REST APIs are essential for building modern applications. Laravel makes it incredibly easy to create robust APIs. In this tutorial, I'll walk you through creating a simple CRUD (Create, Read, Update, Delete) REST API in Laravel Step by Step.
This is laravel api tutorial for beginners that contain laravel 12 crud api example
with product
Prerequisites
- Basic PHP and Laravel knowledge
- Laravel installer installed on your system
- Composer installed
- Database setup (MySQL, PostgreSQL, SQLite, etc.)
Step 1: Create a New Laravel Project
First, let's create a new Laravel project:
laravel new laravel-rest-api
cd laravel-rest-api
This command sets up a new Laravel project named laravel-rest-api
and navigates into the project directory
When you run this command installer ask you for Starter Kits you want to install or not choose option none:
Step 2: Set Up Database Configuration
Configure your database in the .env file:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_api
DB_USERNAME=root
DB_PASSWORD=
Ensure that the database named laravel_api
exists. You can create it using your database management tool or via the command line.
Step 3: Create Model and Migration
Let's create a simple Product model with migration:
php artisan make:model Product -m
Now, edit the migration file in database/migrations/xxxx_create_products_table.php:
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('description');
$table->decimal('price', 8, 2);
$table->timestamps();
});
}
After defining the schema, run the migration to create the products
table:
php artisan migrate
Step 4: Create Form Request for Validation
Laravel's Form Requests provide a dedicated class for validation logic. Let's create one for our Product:
php artisan make:request ProductRequest
Edit app/Http/Requests/ProductRequest.php:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ProductRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|string|max:255',
'description' => 'required|string',
'price' => 'required|numeric|min:0',
];
}
public function messages()
{
return [
'name.required' => 'The product name is required',
'description.required' => 'Please provide a product description',
'price.required' => 'The product price is required',
'price.numeric' => 'Price must be a number',
'price.min' => 'Price cannot be negative',
];
}
}
Step 5: Create API Controller
Generate an API controller:
php artisan make:controller API/ProductController --api
Now implement the controller (app/Http/Controllers/API/ProductController.php):
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\ProductRequest;
use App\Http\Resources\ProductResource;
use App\Models\Product;
use Illuminate\Http\JsonResponse;
class ProductController extends Controller
{
/**
* Display a listing of products.
*/
public function index(): JsonResponse
{
$products = Product::all();
return response()->json([
'success' => true,
'data' => ProductResource::collection($products),
'message' => 'Products retrieved successfully'
]);
}
/**
* Store a newly created product.
*/
public function store(ProductRequest $request): JsonResponse
{
$product = Product::create($request->validated());
return response()->json([
'success' => true,
'data' => new ProductResource($product),
'message' => 'Product created successfully'
], 201);
}
/**
* Display the specified product.
*/
public function show(Product $product): JsonResponse
{
return response()->json([
'success' => true,
'data' => new ProductResource($product),
'message' => 'Product retrieved successfully'
]);
}
/**
* Update the specified product.
*/
public function update(ProductRequest $request, Product $product): JsonResponse
{
$product->update($request->validated());
return response()->json([
'success' => true,
'data' => new ProductResource($product),
'message' => 'Product updated successfully'
]);
}
/**
* Remove the specified product.
*/
public function destroy(Product $product): JsonResponse
{
$product->delete();
return response()->json([
'success' => true,
'message' => 'Product deleted successfully'
]);
}
}
Step 6: Create API Resource
API Resources help format your responses consistently:
php artisan make:resource ProductResource
Edit app/Http/Resources/ProductResource.php:
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class ProductResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
'price' => $this->price,
'created_at' => $this->created_at->format('Y-m-d H:i:s'),
'updated_at' => $this->updated_at->format('Y-m-d H:i:s'),
];
}
}
Step 7: Configure API Routes
By default, Laravel does not provide the api.php file. To create this file, we have two methods:
By create custome api.php and register into bootstrap/app.php
Now create the api.php file in the routes directory and register it in the bootstrap/app.php file within the withRouting() function.
bootstrap/app.php;
->withRouting( web: __DIR__.'/../routes/web.php', api: __DIR__.'/../routes/api.php', commands: __DIR__.'/../routes/console.php', health: '/up', )
Set up routes in routes/api.php:
<?php use App\Http\Controllers\API\ProductController; use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::apiResource('products', ProductController::class);
Install using command
php artisan install:api
By default, this command also installs the Sanctum API package, which is used for user token authentication.
Step 8: Test Your API
Use tools like Postman or cURL to send HTTP requests to your API. Here are the endpoints:
GET
/api/products
: Retrieve all products.POST
/api/products
: Create a new product.GET
/api/products/{id}
: Retrieve a specific product.PUT/PATCH
/api/products/{id}
: Update a specific product.DELETE
/api/products/{id}
: Delete a specific product.
Ensure to include the necessary data in the request body for POST and PUT/PATCH requests.
Conclusion
In this comprehensive guide, we've built a professional-grade REST API in Laravel with:
- Proper validation using Form Requests
- Clean controller structure
- Consistent response formatting with API Resources
- Proper error handling
This approach provides several benefits:
- Separation of concerns: Validation logic lives in dedicated classes
- Consistency: All responses follow the same structure
- Maintainability: Easy to update validation rules without touching controller logic
- Scalability: Ready to add features like authentication, caching, etc.
To further enhance your API, consider adding:
- 🔐 Authentication & Security
- Laravel Sanctum for Token-Based Authentication (Lightweight API auth)
- Laravel Passport for OAuth2 Authentication (Full OAuth2 server for APIs)
- JWT Authentication with Laravel (Stateless token-based auth for scalability)
- ⏱ Rate Limiting
- Prevent abuse by limiting API requests per minute using Laravel's built-in throttle middleware.
- ⚡ Caching Strategies
- Improve performance with Redis or database caching for frequently accessed data.
- 🔍 Advanced Query Filtering
- Implement filtering, sorting, and pagination for better API usability.
- 🧪 Automated Testing
- Write PHPUnit or Pest tests to ensure API reliability and prevent regressions.
By implementing these features, your API will be secure, performant, and production-ready.
Final Thoughts
Laravel provides an excellent ecosystem for API development. Whether you're building a simple CRUD API or a complex microservice, following these best practices ensures clean, maintainable, and scalable code.
🚀 Ready to level up? Check out our in-depth guides on API authentication, rate limiting, and caching strategies!
Happy coding! 🎉