📖 1 minute read
Instead of creating separate controllers for nested resources (like PostCommentController, UserCommentController), build one controller with flexible filtering using Spatie Query Builder.
Before: Multiple Controllers
// app/Http/Controllers/PostCommentController.php
public function index(Post $post)
{
return CommentResource::collection(
$post->comments()->paginate()
);
}
// app/Http/Controllers/UserCommentController.php
public function index(User $user)
{
return CommentResource::collection(
$user->comments()->paginate()
);
}
After: Single Controller with Filters
// app/Http/Controllers/CommentController.php
public function index(Request $request)
{
$query = QueryBuilder::for(Comment::query())
->allowedFilters([
AllowedFilter::callback('post_id',
fn ($q, $value) => $q->where('post_id', $value)
),
AllowedFilter::callback('user_id',
fn ($q, $value) => $q->where('user_id', $value)
),
AllowedFilter::exact('status'),
])
->defaultSort('-created_at');
return CommentResource::collection($query->jsonPaginate());
}
Usage
# Get comments for a post
GET /api/comments?filter[post_id]=123
# Get comments by a user
GET /api/comments?filter[user_id]=456
# Combine filters
GET /api/comments?filter[post_id]=123&filter[status]=approved
Benefits
- Single source of truth for filtering logic
- Easier to maintain and test
- More flexible API for consumers
- Reduces route bloat
Leave a Reply