startsoft / lumina
Automatic REST API generation for Laravel Eloquent models with built-in security, validation, and advanced querying
Requires
- php: ^8.0
- spatie/laravel-query-builder: ^6.2
Requires (Dev)
- orchestra/testbench: ^10.0
- phpunit/phpunit: ^11.0
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 startsoft/lumina dev-main php artisan lumina:install
The interactive installer will guide you through configuring:
- Config & routes - Publishes
config/lumina.phpand route files - Multi-tenant support - Organizations, roles, middleware, and seeders
- Audit trail - Change logging migration
- Cursor AI toolkit - Rules, skills, and agents for AI-assisted development
โโโ โโโ โโโโโโโ โโโโโโโโโโโ โโโ โโโโโโ
โโโ โโโ โโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโ
โโโ โโโ โโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโ
โโโ โโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโ โโโ โโโโโโโโโ โโโโโโโโโ โโโ
โโโโโโโโ โโโโโโโ โโโ โโโโโโโโโ โโโโโโโโ โโโ
+ Lumina :: Install :: Let's build something great +
โ Which features would you like to configure? โโโโโโโโ
โ โผ Publish config & routes โ
โ โป Multi-tenant support (Organizations, Roles) โ
โ โป Audit trail (change logging) โ
โ โป Cursor AI toolkit (rules, skills, agents) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ 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); }); }
โ๏ธ Artisan Commands
| Command | Description |
|---|---|
lumina:install |
Interactive installer โ publish config, enable multi-tenancy, audit trail, and Cursor AI toolkit |
lumina:generate (lumina:g) |
Interactive generator โ scaffold Models (with migration, factory, config registration), Policies, and Scopes |
lumina:export-postman |
Generate a Postman Collection v2.1 for all registered models |
invitation:link |
Generate an invitation link for testing |
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Development Setup
# Clone repository git clone https://github.com/startsoft-dev/lumina-server.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