startsoft / lumina
Automatic REST API generation for Laravel Eloquent models with built-in security, validation, and advanced querying
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/startsoft/lumina
Requires
- php: ^8.0
- spatie/laravel-query-builder: ^6.2
Requires (Dev)
- orchestra/testbench: ^10.0
- phpunit/phpunit: ^11.0
This package is not auto-updated.
Last update: 2026-02-10 12:45:36 UTC
README
Automatic REST API generation for Laravel Eloquent models with built-in security, validation, and advanced querying.
โจ Features
- ๐ Automatic CRUD API - Register a model, get full REST endpoints instantly
- ๐ Built-in Authentication - Login, logout, password recovery out of the box
- ๐ก๏ธ Authorization - Laravel Policy integration with permission-based access control
- โ Validation - Role-based validation rules with automatic request validation
- ๐ Advanced Querying - Filtering, sorting, search, pagination, field selection
- ๐๏ธ Soft Deletes - Automatic trash, restore, and force-delete endpoints
- ๐ Nested Operations - Multi-model atomic transactions in single request
- ๐ Audit Trail - Automatic change logging for compliance
- ๐ข Multi-Tenancy - Organization-based data isolation built-in
- ๐ง Invitations - User invitation system with email workflow
- โก High Performance - Header-based pagination, query optimization
- ๐ฏ Type-Safe - Model-driven API with explicit route registration
๐ฆ Installation
composer require lumina/laravel-api php artisan lumina:publish
๐ Quick Start
1. Register Your Model
Edit config/lumina.php:
return [ 'models' => [ 'posts' => \App\Models\Post::class, ], ];
2. Add Validation Trait
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Lumina\LaravelApi\Traits\HasValidation; class Post extends Model { use HasValidation; protected $fillable = ['title', 'content', 'user_id']; // Validation rules protected $validationRules = [ 'title' => 'string|max:255', 'content' => 'string', 'user_id' => 'exists:users,id', ]; protected $validationRulesStore = [ 'title' => 'required', 'content' => 'required', 'user_id' => 'required', ]; protected $validationRulesUpdate = [ 'title' => 'sometimes', 'content' => 'sometimes', ]; // Query Builder configuration public static $allowedFilters = ['title', 'user_id']; public static $allowedSorts = ['created_at', 'title']; public static $defaultSort = '-created_at'; public static $allowedIncludes = ['user']; }
3. Create Policy
php artisan make:policy PostPolicy --model=Post
<?php namespace App\Policies; use App\Models\User; use App\Models\Post; use Lumina\LaravelApi\Policies\ResourcePolicy; class PostPolicy extends ResourcePolicy { public function viewAny(?User $user) { return true; } public function view(?User $user, Post $post) { return true; } public function create(?User $user) { return $user !== null; } public function update(?User $user, Post $post) { return $user && $user->id === $post->user_id; } public function delete(?User $user, Post $post) { return $user && $user->id === $post->user_id; } }
4. Done! ๐
Your API endpoints are now available:
GET /api/posts # List posts POST /api/posts # Create post GET /api/posts/{id} # Show post PUT /api/posts/{id} # Update post DELETE /api/posts/{id} # Delete post
๐ Requirements
- PHP: 8.0+
- Laravel: 10+
- Spatie Query Builder: ^6.2
๐ Documentation
Getting Started
- Installation & Setup - Complete installation guide and first steps
- API Reference - Full endpoint documentation with examples
Core Features
| Feature | Documentation |
|---|---|
| ๐ Authentication | Authentication Guide - Login, logout, password recovery |
| ๐ก๏ธ Authorization | Authorization Guide - Permissions and policies |
| โ Validation | Validation Guide - Role-based validation |
| ๐ Query Builder | Query Builder Guide - Filtering, sorting, includes |
| ๐ Pagination | Pagination Guide - Header-based pagination |
| ๐๏ธ Soft Deletes | Soft Deletes Guide - Trash and restore |
| ๐ Audit Trail | Audit Trail Guide - Change tracking |
| ๐ Nested Operations | Nested Operations Guide - Multi-model transactions |
| ๐ข Multi-Tenancy | Multi-Tenancy Guide - Organization isolation |
| ๐ง Invitations | Invitations Guide - User invitation system |
๐ฏ Key Concepts
Automatic CRUD Generation
Register a model and get full REST API endpoints with zero controller code:
// config/lumina.php 'models' => [ 'posts' => \App\Models\Post::class, ],
All routes are explicitly registered and visible via php artisan route:list.
Permission-Based Authorization
Use Laravel policies with convention-based permissions stored in JSON:
// Permission format: {slug}.{action} 'permissions' => [ 'posts.index', // Can list posts 'posts.store', // Can create posts 'posts.*', // All post actions '*', // All permissions ]
Advanced Query Builder
Built on Spatie Query Builder with include authorization:
# Complex query in single request GET /api/posts?filter[status]=published&include=user,comments&sort=-created_at&per_page=20 # Include authorization - returns 403 if user cannot view comments GET /api/posts?include=comments
Role-Based Validation
Different validation rules per user role:
protected $validationRulesStore = [ 'admin' => [ 'title' => 'required', 'content' => 'required', 'is_published' => 'nullable', // Admins can publish ], 'contributor' => [ 'title' => 'required', 'content' => 'required', // Contributors cannot set is_published ], ];
Multi-Model Transactions
Execute multiple operations atomically:
POST /api/nested
{
"operations": [
{
"model": "blogs",
"action": "create",
"data": {"title": "My Blog"}
},
{
"model": "posts",
"action": "create",
"data": {"blog_id": 1, "title": "First Post"}
}
]
}
Audit Trail
Automatic change tracking:
use Lumina\LaravelApi\Traits\HasAuditTrail; class Post extends Model { use HasAuditTrail; } // Automatically logs: // - Created, updated, deleted, restored events // - Old and new values // - User, organization, IP, user agent
๐ง Configuration
Model Configuration
class Post extends Model { use HasValidation; // Query Builder public static $allowedFilters = ['title', 'status', 'user_id']; public static $allowedSorts = ['created_at', 'updated_at', 'title']; public static $defaultSort = '-created_at'; public static $allowedFields = ['id', 'title', 'content']; public static $allowedIncludes = ['user', 'comments']; public static $allowedSearch = ['title', 'content']; // Pagination public static bool $paginationEnabled = true; protected $perPage = 25; // Middleware public static array $middleware = ['throttle:60,1']; public static array $middlewareActions = [ 'store' => ['verified'], 'update' => ['verified'], ]; // Exclude actions public static array $exceptActions = ['destroy']; }
Global Configuration
Edit config/lumina.php:
return [ // Model registration 'models' => [ 'posts' => \App\Models\Post::class, 'comments' => \App\Models\Comment::class, ], // Public endpoints (no auth required) 'public' => ['posts'], // Nested operations 'nested_operations' => [ 'enabled' => true, 'max_operations' => 10, 'allowed_models' => ['blogs', 'posts', 'comments'], ], // Authentication 'auth' => [ 'login_route' => 'api/auth/login', 'logout_route' => 'api/auth/logout', 'password_recovery_enabled' => true, 'registration_enabled' => true, ], ];
๐ Examples
Filtering
# Single filter GET /api/posts?filter[is_published]=true # Multiple filters (AND) GET /api/posts?filter[is_published]=true&filter[user_id]=1 # Multiple values (OR) GET /api/posts?filter[status]=draft,published
Sorting
# Ascending GET /api/posts?sort=title # Descending GET /api/posts?sort=-created_at # Multiple sorts GET /api/posts?sort=-is_published,created_at
Includes (Eager Loading)
# Single relationship GET /api/posts?include=user # Multiple relationships GET /api/posts?include=user,comments,tags # Nested relationships GET /api/posts?include=comments.user
Pagination
# On-demand pagination GET /api/posts?per_page=20&page=2 # With other query features GET /api/posts?filter[status]=published&sort=-created_at&include=user&per_page=20
Pagination metadata in headers:
X-Current-Page: 2
X-Last-Page: 10
X-Per-Page: 20
X-Total: 195
Field Selection
# Select specific fields GET /api/posts?fields[posts]=id,title,created_at # With relationships GET /api/posts?include=user&fields[posts]=id,title&fields[users]=id,name
Search
# Full-text search GET /api/posts?search=laravel # Search with filters GET /api/posts?search=tutorial&filter[is_published]=true
๐๏ธ Architecture
Request Flow
1. Request โ Middleware (auth, organization context)
โ
2. GlobalController resolves model
โ
3. Policy authorization check
โ
4. Query Builder applies filters/sorts/includes
โ
5. Include authorization (per relationship)
โ
6. Model validation (create/update)
โ
7. Database operation
โ
8. Audit logging (if enabled)
โ
9. Response with data + pagination headers
Built With
- Laravel - PHP framework
- Spatie Query Builder - Advanced querying
- Laravel Sanctum - API authentication
- Laravel Policies - Authorization
- Eloquent ORM - Database operations
๐ก๏ธ Security
Authorization
All endpoints are protected by Laravel policies:
// Automatically checks: // - viewAny() for index // - view() for show // - create() for store // - update() for update // - delete() for delete/destroy
Validation
All create/update requests validated:
// Prevents invalid data from reaching database // Role-based rules for different user types // Custom error messages
Query Scopes
Add automatic filtering:
protected static function booted() { static::addGlobalScope(new OrganizationScope); }
Rate Limiting
Per-model rate limiting:
public static array $middleware = ['throttle:60,1'];
๐งช Testing
Example Tests
use Tests\TestCase; class PostApiTest extends TestCase { public function test_can_list_posts() { Post::factory()->count(5)->create(); $response = $this->getJson('/api/posts'); $response->assertOk() ->assertJsonCount(5); } public function test_can_filter_posts() { Post::factory()->create(['is_published' => true]); Post::factory()->create(['is_published' => false]); $response = $this->getJson('/api/posts?filter[is_published]=true'); $response->assertOk() ->assertJsonCount(1); } public function test_cannot_create_post_without_auth() { $response = $this->postJson('/api/posts', [ 'title' => 'Test', 'content' => 'Content', ]); $response->assertStatus(401); } public function test_can_include_relationships() { $post = Post::factory()->create(); $response = $this->getJson('/api/posts?include=user'); $response->assertOk() ->assertJsonStructure([ '*' => ['id', 'title', 'user' => ['id', 'name']] ]); } }
๐ Performance
Optimizations
- Lazy Loading Prevention - Use
$allowedIncludesfor explicit relationships - Query Optimization - Spatie Query Builder optimizes SQL queries
- Pagination - Limits result sets with configurable defaults
- Field Selection - Reduces payload size by selecting specific fields
- Header-Based Pagination - Keeps response body clean and consistent
Caching
Add caching to expensive queries:
public function index(Request $request) { $cacheKey = 'posts_' . md5($request->fullUrl()); return Cache::remember($cacheKey, 60, function () use ($request) { return Post::query() ->allowedFilters(['title', 'status']) ->paginate(20); }); }
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Development Setup
# Clone repository git clone https://github.com/lumina/laravel-api.git # Install dependencies composer install # Run tests php artisan test
๐ License
This package is open-sourced software licensed under the MIT license.
๐ Links
- Documentation - Complete documentation
- API Reference - Endpoint reference
- Changelog - Version history
- Issues - Report bugs
- Discussions - Ask questions
๐ Credits
- Built with Laravel
- Query building powered by Spatie Query Builder
- Inspired by best practices from the Laravel community
Made with โค๏ธ by Startsoft