DEV Community

David Chamling Rai
David Chamling Rai

Posted on

Building a Complete Blog API with Laravel API CRUD Generator

๐Ÿš€ Quickly build feature-rich, production-ready Laravel APIs with clean architecture using the Laravel API CRUD Generator.

This tutorial walks you through building a complete Blog API using the https://github.com/wadangkaa/laravel-api-crud. Youโ€™ll learn how to scaffold models, controllers, requests, services, resources, and routes in minutes โ€” all following Laravel best practices.

Weโ€™ll cover:

  • Installation & Setup
  • Request validation
  • Route generation
  • Search and filtering
  • Lifecycle hooks

Whether youโ€™re a beginner or an experienced Laravel developer, this guide will help you rapidly prototype and scale your APIs with confidence.

Prerequisites:

  • PHP 8.0+
  • Composer
  • Laravel 9 or higher
  • Basic Laravel knowledge

Step 1: Create a New Laravel Project

laravel new blog-api
cd blog-api
Enter fullscreen mode Exit fullscreen mode

Step 2: Install Laravel API CRUD Generator

composer require david-chamling/laravel-api-crud
Enter fullscreen mode Exit fullscreen mode

Step 3: Generate Blog Post CRUD

php artisan make:crud Post
Enter fullscreen mode Exit fullscreen mode

This generates:

  • Post model
  • PostController
  • Store/Update PostRequests
  • Post resources
  • PostCrudService
  • Post migration

Step 4: Configure the Post Model
Update app/Models/Post.php:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $fillable = [
        'title',
        'content',
        'status',
        'published_at'
    ];

    protected $casts = [
        'published_at' => 'datetime',
  ];
}
Enter fullscreen mode Exit fullscreen mode

Step 5: Set Up Database Migration
Update the generated post migration:

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('content');
    $table->string('status')->default('draft');
    $table->timestamp('published_at')->nullable();
    $table->timestamps();
});
Enter fullscreen mode Exit fullscreen mode

Run migrations:

php artisan migrate
Enter fullscreen mode Exit fullscreen mode

Step 6: Configure Requests
Update app/Http/Requests/Post/StorePostRequest.php:

public function rules(): array
{
    return [
        'title' => 'required|string|max:255',
        'content' => 'required|string',
        'status' => 'required|in:draft,published,archived',
        'published_at' => 'nullable|date'
    ];
}
Enter fullscreen mode Exit fullscreen mode

Update UpdatePostRequest.php:

public function rules(): array
{
    return [
        'title' => 'sometimes|string|max:255',
        'content' => 'sometimes|string',
        'status' => 'sometimes|in:draft,published,archived',
        'published_at' => 'nullable|date'
    ];
}
Enter fullscreen mode Exit fullscreen mode

Step 7: Set Up API Routes
In routes/api.php:

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;

Route::crudResource('post', PostController::class);
Enter fullscreen mode Exit fullscreen mode

Run artisan route list comment to check newly created routes

php artisan route:list
Enter fullscreen mode Exit fullscreen mode

Step 8: Testing CRUD Operations

Create Post

POST /api/post
Content-Type: application/json
{
"title": "My First Post",
"content": "This is the content",
"status": "draft"
}
Enter fullscreen mode Exit fullscreen mode

Get All Posts

GET /api/post
Enter fullscreen mode Exit fullscreen mode

Get Single Post

GET /api/post/1
Enter fullscreen mode Exit fullscreen mode

Update Post

PUT /api/post/1
Content-Type: application/json
{
"status": "published"
}
Enter fullscreen mode Exit fullscreen mode

Delete Post

DELETE /api/post/1
Enter fullscreen mode Exit fullscreen mode

Step 9: Adding Search Functionality
Update app/Http/Controllers/PostController.php:

protected array $searchableColumns = ['title'];
protected array $searchableRelations = [
  'author' => ['name'], // Search author via name (author relation required)
];
protected int $paginationNumber = 15;
Enter fullscreen mode Exit fullscreen mode

Search Functionality Examples

The CRUD controller provides powerful search capabilities out of the box. Here are comprehensive examples:

Basic Search Syntax

GET /api/post?search={keyword}
GET /api/post?filter[{field}]={value}
GET /api/post?sort_by={field}&sort_order={asc|desc}
GET /api/post?per_page={number}
Enter fullscreen mode Exit fullscreen mode

Complete Example with Parameters

GET /api/post?
    search=Laravel&
    filter[status]=published&
    filter[category.id]=5&
    sort_by=created_at&
    sort_order=desc&
    per_page=15
Enter fullscreen mode Exit fullscreen mode

Step 10: Implementing Lifecycle Hooks (Optional)
Update app/Services/Crud/PostCrudService.php:

public function beforeStore(array $data): array
{
    $data['slug'] = \Str::slug($data['title']); //if you add slug field
    return $data;
}
public function afterStore(Model $model): void
{
    \Log::info("New post created: {$model->title}");
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

Weโ€™ve built a complete blog API with:

  1. CRUD operations
  2. Search and filtering
  3. Optional lifecycle hooks

The Laravel API CRUD Generator package makes API development faster while maintaining clean code.

Key features used:

  1. Automatic route generation
  2. Built-in search capabilities
  3. Customizable validation
  4. Flexible resource transformation

For more advanced usage, check the GitHub: https://github.com/wadangkaa/laravel-api-crud

Top comments (2)

Collapse
 
nevodavid profile image
Nevo David

nicely put-together tbh, breaking things into these steps helps me not overthink. you think building with generators like this changes long-term maintenance or nah?

Collapse
 
wadangkaa profile image
David Chamling Rai

Thanks! You should definitely give it a try โ€” I'd love to hear your thoughts.
For long-term maintenance, I'm open to any ideas that could make it even better!