1. Go to this page and download the library: Download anil/fast-api-crud library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
anil / fast-api-crud example snippets
// app/Http/Controllers/PostController.php
class PostController extends BaseController
{
public function __construct()
{
parent::__construct(
model: Post::class,
storeRequest: StorePostRequest::class,
updateRequest: UpdatePostRequest::class,
resource: PostResource::class,
);
}
}
class Post extends Model
{
// Called before/after store()
public function beforeCreate(): void
{
$this->slug = Str::slug($this->name);
}
public function afterCreate(): void
{
// Sync relations from request
if (request()->filled('tag_ids')) {
$this->tags()->sync(request()->input('tag_ids'));
}
}
// Called before/after update()
public function beforeUpdate(): void { }
public function afterUpdate(): void { }
// Called before/after destroy() and delete()
public function beforeDelete(): void { }
public function afterDelete(): void { }
// Called before/after changeStatus()
public function beforeStatusChange(): void { }
public function afterStatusChange(): void { }
// Called before/after updateColumn()
public function beforeColumnUpdate(): void { }
public function afterColumnUpdate(): void { }
// Called before/after restore()
public function beforeRestore(): void { }
public function afterRestore(): void { }
// Called before/after permanentDelete()
public function beforeForceDelete(): void { }
public function afterForceDelete(): void { }
}
class PostController extends BaseController
{
protected function afterCreate(Model $model): void
{
// Controller-level hook overrides model hook
Notification::send($admins, new PostCreated($model));
}
}
use Anil\FastApiCrud\Contracts\Searchable;
class Post extends Model implements Searchable
{
public function searchableColumns(): array
{
return [
'name',
'desc',
'user:name,email', // Search in related model columns
];
}
}
use Anil\FastApiCrud\Contracts\Sortable;
class Post extends Model implements Sortable
{
public function sortByDefaults(): array
{
return [
'sortBy' => 'created_at',
'sortByDesc' => true,
];
}
}
use Anil\FastApiCrud\Contracts\HasPermissionSlug;
class Post extends Model implements HasPermissionSlug
{
public function getPermissionSlug(): string
{
return 'posts';
}
}
use Anil\FastApiCrud\Concerns\HasDateScopes;
class Post extends Model
{
use HasDateScopes;
}
Post::query()->today(); // Records from today
Post::query()->yesterday(); // Records from yesterday
Post::query()->thisWeek(); // Monday to now
Post::query()->lastWeek(); // Last Monday to Sunday
Post::query()->monthToDate(); // 1st of month to now
Post::query()->thisMonth(); // Entire current month
Post::query()->lastMonth(); // Entire previous month
Post::query()->quarterToDate(); // Start of quarter to now
Post::query()->lastQuarter(); // Previous quarter
Post::query()->yearToDate(); // January 1 to now
Post::query()->lastYear(); // Last 12 months
Post::query()->last7Days(); // Last 7 days
Post::query()->last30Days(); // Last 30 days
Post::query()->date('2025-01-01 to 2025-01-31'); // Custom range
// Use a different column
Post::query()->today('published_at');
Post::query()->lastMonth('updated_at');
use Illuminate\Database\Eloquent\Concerns\HasUuids; // UUID v7 (time-ordered, recommended)
// use Illuminate\Database\Eloquent\Concerns\HasVersion4Uuids; // ordered UUID
class Post extends Model
{
use HasUuids;
}
use Anil\FastApiCrud\Concerns\AnonymizesOnDelete;
class User extends Model
{
use SoftDeletes, AnonymizesOnDelete;
}
use Anil\FastApiCrud\Concerns\ReplicatesWithRelations;
class Post extends Model
{
use ReplicatesWithRelations;
}
// Usage
$post = Post::with(['tags', 'comments', 'author'])->find(1);
$clone = $post->replicateWithRelations();
// $clone is a saved copy with all relations duplicated
// Basic — posts that have at least 1 comment, with comment count
Post::query()->withCountWhereHas('comments');
// With callback — posts with approved comments
Post::query()->withCountWhereHas('comments', function ($q) {
$q->where('approved', true);
});
// With operator/count — posts with 5+ comments
Post::query()->withCountWhereHas('comments', null, '>=', 5);
// OR variant — posts with comments OR tags
Post::query()
->withCountWhereHas('comments')
->orWithCountWhereHas('tags');
use Anil\FastApiCrud\Support\Pagination;
Pagination::defaultPerPage(); // 15 (from config)
Pagination::maxPerPage(); // 100 (from config)
Pagination::requestedPerPage(15); // Value of ?rowsPerPage or default
Pagination::resolvePerPage(); // Effective per-page (respects max, allow_all)
// Generic config helpers
Pagination::configInt('fast-api.pagination.default_per_page', 15); // int
Pagination::configBool('fast-api.pagination.allow_all', true); // bool
use Anil\FastApiCrud\Enums\PaginationType;
PaginationType::LengthAware // 'length-aware' — Standard pagination with total count
PaginationType::Simple // 'simple' — Simple pagination without total
PaginationType::Cursor // 'cursor' — Cursor-based pagination
PaginationType::None // 'none' — No pagination, returns all records
namespace App\Models;
use Anil\FastApiCrud\Concerns\HasDateScopes;
use Anil\FastApiCrud\Concerns\AnonymizesOnDelete;
use Anil\FastApiCrud\Contracts\HasPermissionSlug;
use Anil\FastApiCrud\Contracts\Searchable;
use Anil\FastApiCrud\Contracts\Sortable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model implements Searchable, Sortable, HasPermissionSlug
{
use SoftDeletes, HasDateScopes, AnonymizesOnDelete;
protected $fillable = ['name', 'desc', 'status', 'active', 'user_id'];
// --- Contracts ---
public function searchableColumns(): array
{
return ['name', 'desc', 'user:name,email'];
}
public function sortByDefaults(): array
{
return ['sortBy' => 'created_at', 'sortByDesc' => true];
}
public function getPermissionSlug(): string
{
return 'posts';
}
// --- Relations ---
public function user()
{
return $this->belongsTo(User::class);
}
public function tags()
{
return $this->belongsToMany(Tag::class);
}
// --- Scopes (callable via ?filters={"active":1}) ---
public function scopeActive($query, int $active = 1)
{
return $query->where('active', $active);
}
// --- Lifecycle Hooks ---
public function afterCreate(): void
{
if (request()->filled('tag_ids')) {
$this->tags()->sync(request()->input('tag_ids'));
}
}
public function afterUpdate(): void
{
if (request()->filled('tag_ids')) {
$this->tags()->sync(request()->input('tag_ids'));
}
}
}
namespace App\Http\Controllers\Api;
use Anil\FastApiCrud\Enums\PaginationType;
use Anil\FastApiCrud\Http\Controllers\BaseController;
use App\Http\Requests\Post\StorePostRequest;
use App\Http\Requests\Post\UpdatePostRequest;
use App\Http\Resources\Post\PostResource;
use App\Models\Post;
class PostController extends BaseController
{
protected PaginationType $paginationType = PaginationType::LengthAware;
protected array $with = ['user', 'tags'];
protected array $withCount = ['tags'];
protected array $load = ['user', 'tags', 'tags.posts'];
protected array $scopes = ['active'];
public function __construct()
{
parent::__construct(
model: Post::class,
storeRequest: StorePostRequest::class,
updateRequest: UpdatePostRequest::class,
resource: PostResource::class,
);
}
}
namespace App\Http\Controllers\Web;
use Anil\FastApiCrud\Http\Controllers\BaseWebController;
use App\Http\Requests\Post\StorePostRequest;
use App\Http\Requests\Post\UpdatePostRequest;
use App\Models\Post;
class PostController extends BaseWebController
{
protected array $with = ['user', 'tags'];
protected array $load = ['user', 'tags'];
public function __construct()
{
parent::__construct(
model: Post::class,
storeRequest: StorePostRequest::class,
updateRequest: UpdatePostRequest::class,
viewPrefix: 'posts',
routePrefix: 'posts',
resourceName: 'post',
collectionName: 'posts',
);
}
protected function storeSuccessMessage(): string
{
return __('Post created successfully!');
}
}