laravel-architex / architecture-generator
Laravel Architecture Generator - A powerful tool to generate project structure based on popular architecture patterns
Requires
- php: ^7.4|^8.0|^8.1
- illuminate/console: ^8.0|^9.0|^10.0|^11.0
- illuminate/filesystem: ^8.0|^9.0|^10.0|^11.0
- illuminate/support: ^8.0|^9.0|^10.0|^11.0
- laravel/framework: ^8.0|^9.0|^10.0|^11.0
Requires (Dev)
- orchestra/testbench: ^6.0|^7.0|^8.0
- phpunit/phpunit: ^9.0
Suggests
- barryvdh/laravel-debugbar: For debugging generated architecture components
- laravel/ide-helper: For better IDE support with generated classes
This package is not auto-updated.
Last update: 2025-08-16 11:51:05 UTC
README
Laravel Architex is a powerful tool that helps Laravel developers quickly initialize project structure based on popular architecture patterns, automatically generating folders, classes, interfaces, service providers, and necessary files based on templates.
๐ Key Features
Supported Architectures:
- DDD (Domain Driven Design) - Create 4-layer structure: Domain, Application, Infrastructure, UI
- Repository Pattern - Create interface and implementation for repositories
- Service Layer - Create service classes with basic methods
- CQRS (Command Query Responsibility Segregation) - Create commands, queries and handlers
- Event Bus - Create events and listeners
- Modular/Package-based Architecture - Create complete module structure with controllers, models, services, repositories, routes, config, tests, and more
- Hexagonal Architecture (Ports and Adapters) - Create clean architecture with domain isolation, ports, and adapters
Additional Features:
- โ Configurable naming conventions (class names, interfaces, namespaces, folder structure)
- โ Integrated Artisan commands for quick component generation
- โ Template engine (stub files) for customizing generated code
- โ
Configuration through
architex.php
file in config/ - โ Auto registration in service providers
๐ฆ Installation
System Requirements:
- PHP >= 7.4
- Laravel >= 8.0
Quick Setup (Recommended)
# Clone repository git clone <repository-url> cd Laravel-Architecture-Generator # Run automated setup chmod +x setup.sh ./setup.sh
Manual Installation
# Install package composer require laravel-architex/architecture-generator # Publish configuration php artisan vendor:publish --tag=architex-config
For Development/Testing
# Install package dependencies composer install # Run package tests chmod +x run-tests.sh ./run-tests.sh all # Create test Laravel app composer create-project laravel/laravel test-laravel-app cd test-laravel-app # Install Laravel Architex composer config repositories.laravel-architex path ../ composer require laravel-architex/architecture-generator:dev-main # Publish configuration php artisan vendor:publish --tag=architex-config # Fix missing files (if needed) chmod +x fix-missing-files.sh ./fix-missing-files.sh
Setup RepositoryService
# Register RepositoryServiceProvider in config/app.php # Add to providers array: App\Providers\RepositoryServiceProvider::class, # Or use the provided service provider from Laravel Architex # It will be automatically registered when you publish the config
Quick Start with RepositoryService:
// In your controller class UserController extends Controller { public function index() { // That's it! No need to create individual repositories $users = Repository::model(User::class)->paginate(15); return response()->json($users); } }
๐ ๏ธ Usage
1. Repository Pattern
Option A: Traditional Repository Pattern
# Create repository for User model php artisan make:repository User # Create repository with custom model php artisan make:repository User --model=App\Models\User # Overwrite existing files php artisan make:repository User --force
Result:
app/Repositories/Interfaces/UserRepositoryInterface.php
app/Repositories/UserRepository.php
(extends BaseRepository)
Option B: RepositoryService Pattern (Recommended)
# No need to create individual repositories! # Just use RepositoryService for all models
Usage:
// Clean and simple! $users = Repository::model(User::class)->paginate(15); $posts = Repository::model(Post::class)->findWhere(['status' => 'published']); $orders = Repository::model(Order::class)->with('items')->all();
Benefits:
- โ No need to create individual repository classes
- โ Single service handles all models
- โ Clean Facade syntax
- โ Easy to test and mock
- โ Consistent API across all models
Base Repository Features:
- โ Full CRUD operations (create, read, update, delete)
- โ Advanced query methods (findWhere, findWhereIn, etc.)
- โ Pagination support
- โ Criteria pattern for complex queries
- โ Presenter pattern support
- โ Validation integration
- โ Event dispatching
- โ Relationship handling
- โ Search functionality
- โ Ordering and limiting
- โ Scope queries
RepositoryService Pattern (Recommended):
- โ Single service for all models
- โ Clean Facade syntax
- โ Dependency injection ready
- โ Contract-based architecture
- โ Easy to test and mock
- โ Reusable across the application
Usage Examples:
1. Using RepositoryService (Recommended)
// In your controller class UserController extends Controller { protected $repositoryService; public function __construct(RepositoryServiceInterface $repositoryService) { $this->repositoryService = $repositoryService; } public function index() { // Set model and get all users with pagination $users = $this->repositoryService->model(\App\Models\User::class)->paginate(15); // Find by criteria $activeUsers = $this->repositoryService->model(\App\Models\User::class) ->findWhere(['status' => 'active']); // Advanced search $searchResults = $this->repositoryService->model(\App\Models\User::class) ->findWhere([ 'name' => ['LIKE', '%john%'], 'created_at' => ['DATE', '>=', '2023-01-01'] ]); // With relationships $usersWithPosts = $this->repositoryService->model(\App\Models\User::class) ->with('posts')->all(); return response()->json($users); } }
2. Using Repository Facade
// In your controller class UserController extends Controller { public function index() { // Using Facade - much cleaner! $users = Repository::model(\App\Models\User::class)->paginate(15); $activeUsers = Repository::model(\App\Models\User::class) ->findWhere(['status' => 'active']); $searchResults = Repository::model(\App\Models\User::class) ->findWhere([ 'name' => ['LIKE', '%john%'], 'created_at' => ['DATE', '>=', '2023-01-01'] ]); $usersWithPosts = Repository::model(\App\Models\User::class) ->with('posts')->all(); return response()->json($users); } }
3. Using Dependency Injection
// In your controller class UserController extends Controller { public function index(RepositoryServiceInterface $repository) { $users = $repository->model(\App\Models\User::class)->paginate(15); return response()->json($users); } }
4. Complete Usage Examples
// CRUD Operations $user = Repository::model(User::class)->create(['name' => 'John', 'email' => 'john@example.com']); $user = Repository::model(User::class)->find(1); $user = Repository::model(User::class)->update(['name' => 'Jane'], 1); Repository::model(User::class)->delete(1); // Find Operations $user = Repository::model(User::class)->findByField('email', 'john@example.com'); $users = Repository::model(User::class)->findWhere(['status' => 'active']); $users = Repository::model(User::class)->findWhereIn('id', [1, 2, 3]); $users = Repository::model(User::class)->findWhereNotIn('id', [1, 2, 3]); $users = Repository::model(User::class)->findWhereBetween('created_at', ['2023-01-01', '2023-12-31']); // Pagination $users = Repository::model(User::class)->paginate(15); $users = Repository::model(User::class)->simplePaginate(15); // Relationships $users = Repository::model(User::class)->with('posts')->all(); $users = Repository::model(User::class)->withCount('posts')->all(); $users = Repository::model(User::class)->whereHas('posts', function($query) { $query->where('status', 'published'); })->all(); // Ordering & Limiting $users = Repository::model(User::class)->orderBy('created_at', 'desc')->all(); $users = Repository::model(User::class)->take(10)->all(); $users = Repository::model(User::class)->limit(10)->all(); // Advanced Search $users = Repository::model(User::class)->findWhere([ 'name' => ['LIKE', '%john%'], 'created_at' => ['DATE', '>=', '2023-01-01'], 'status' => ['IN', ['active', 'pending']] ]); // Count $count = Repository::model(User::class)->count(['status' => 'active']); // First or Create $user = Repository::model(User::class)->firstOrCreate(['email' => 'john@example.com']); $user = Repository::model(User::class)->firstOrNew(['email' => 'john@example.com']); // Update or Create $user = Repository::model(User::class)->updateOrCreate( ['email' => 'john@example.com'], ['name' => 'John Doe'] ); // Sync Relations Repository::model(User::class)->sync(1, 'roles', [1, 2, 3]); Repository::model(User::class)->syncWithoutDetaching(1, 'roles', [1, 2, 3]);
5. Service Provider Registration
// config/app.php 'providers' => [ // ... App\Providers\RepositoryServiceProvider::class, ], // app/Providers/RepositoryServiceProvider.php public function register() { $this->app->singleton('repository', function ($app) { return new RepositoryService(); }); $this->app->bind(RepositoryServiceInterface::class, RepositoryService::class); }
6. Testing with RepositoryService
// tests/Feature/UserTest.php class UserTest extends TestCase { public function test_can_get_users_with_repository() { // Mock the repository service $mockRepository = Mockery::mock(RepositoryServiceInterface::class); $mockRepository->shouldReceive('model') ->with(\App\Models\User::class) ->andReturnSelf(); $mockRepository->shouldReceive('paginate') ->with(15) ->andReturn(collect([])); $this->app->instance(RepositoryServiceInterface::class, $mockRepository); $response = $this->get('/api/users'); $response->assertStatus(200); } }
2. Service Layer
# Create service for User php artisan make:service User # Overwrite existing files php artisan make:service User --force
Result:
app/Services/UserService.php
3. DDD (Domain Driven Design)
# Create complete DDD module php artisan make:ddd UserManagement # Create only specific layers php artisan make:ddd UserManagement --layers=domain,application # Overwrite existing files php artisan make:ddd UserManagement --force
Result:
app/
โโโ Domain/
โ โโโ UserManagement/
โ โโโ Entities/
โ โโโ Repositories/
โ โโโ Services/
โ โโโ Events/
โ โโโ Exceptions/
โโโ Application/
โ โโโ UserManagement/
โ โโโ Services/
โ โโโ Commands/
โ โโโ Queries/
โ โโโ Handlers/
โโโ Infrastructure/
โ โโโ UserManagement/
โ โโโ Repositories/
โ โโโ Services/
โ โโโ Persistence/
โ โโโ External/
โโโ UI/
โโโ UserManagement/
โโโ Controllers/
โโโ Requests/
โโโ Resources/
โโโ Middleware/
4. CQRS (Command Query Responsibility Segregation)
# Create complete CQRS structure php artisan make:cqrs CreateUser # Create only command php artisan make:command CreateUser # Create only query php artisan make:query GetUser # Overwrite existing files php artisan make:cqrs CreateUser --force
Result:
app/Commands/CreateUserCommand.php
app/Queries/GetUserQuery.php
app/Handlers/CreateUserCommandHandler.php
app/Handlers/GetUserQueryHandler.php
5. Event Bus
# Create event and listener php artisan make:event UserCreated # Overwrite existing files php artisan make:event UserCreated --force
Result:
app/Events/UserCreatedEvent.php
app/Listeners/UserCreatedListener.php
6. Modular/Package-based Architecture
# Create complete modular structure php artisan architex:modular UserManagement # Create with specific options php artisan architex:modular UserManagement --with-tests --with-migrations --with-seeders --with-routes --with-config # Create with custom path and namespace php artisan architex:modular UserManagement --path=app/Modules --namespace=App\\Modules # Create with all features php artisan architex:modular UserManagement --with-tests --with-migrations --with-seeders --with-routes --with-config --with-views --with-assets # Overwrite existing files php artisan architex:modular UserManagement --force
Result:
app/Modules/UserManagement/
โโโ Controllers/
โ โโโ UserManagementController.php
โโโ Models/
โ โโโ UserManagement.php
โโโ Services/
โ โโโ UserManagementService.php
โโโ Repositories/
โ โโโ UserManagementRepository.php
โโโ Providers/
โ โโโ UserManagementServiceProvider.php
โโโ Routes/
โ โโโ web.php
โโโ Config/
โ โโโ usermanagement.php
โโโ Views/ (optional)
โโโ Assets/ (optional)
โโโ Database/
โ โโโ Migrations/
โ โ โโโ 2024_01_01_000000_create_user_managements_table.php
โ โโโ Seeders/
โ โโโ UserManagementSeeder.php
โโโ Tests/
โ โโโ UserManagementTest.php
โโโ README.md
Features:
- โ Complete CRUD operations with controllers
- โ Repository pattern implementation
- โ Service layer with business logic
- โ Database migrations and seeders
- โ Comprehensive test coverage
- โ Module configuration management
- โ Route management with middleware
- โ Service provider for module registration
- โ Optional view templates and assets
- โ Documentation and usage examples
7. Hexagonal Architecture (Ports and Adapters)
# Create complete hexagonal structure php artisan architex:hexagonal User # Create with specific options php artisan architex:hexagonal User --with-tests --with-migrations --with-routes # Create with custom path and namespace php artisan architex:hexagonal User --path=app/Hexagonal --namespace=App\\Hexagonal # Create with all features php artisan architex:hexagonal User --with-tests --with-migrations --with-routes --with-config # Overwrite existing files php artisan architex:hexagonal User --force
Result:
app/Hexagonal/User/
โโโ Domain/
โ โโโ Entities/
โ โ โโโ User.php
โ โโโ Ports/
โ โโโ UserRepositoryPort.php
โ โโโ UserServicePort.php
โโโ Application/
โ โโโ Services/
โ โโโ UserApplicationService.php
โโโ Infrastructure/
โ โโโ Adapters/
โ โ โโโ UserRepositoryAdapter.php
โ โโโ database/migrations/
โ โโโ create_users_table.php
โโโ UI/
โ โโโ Adapters/
โ โ โโโ UserControllerAdapter.php
โ โโโ routes/
โ โโโ user_routes.php
โโโ Tests/
โ โโโ UserHexagonalTest.php
โโโ UserServiceProvider.php
Features:
- โ Domain entities with business logic
- โ Port interfaces for dependency inversion
- โ Application services for use cases
- โ Infrastructure adapters for external concerns
- โ UI adapters for primary ports
- โ Service provider for dependency injection
- โ Database migrations and tests
- โ Route management
- โ Clean separation of concerns
โ๏ธ Configuration
Config File: config/architex.php
The configuration file allows you to customize:
- Architecture patterns (DDD, Repository, Service, CQRS, Event Bus, Modular)
- Naming conventions (class names, interfaces, namespaces)
- Template engine settings
- Auto registration options
# Publish config file
php artisan vendor:publish --tag=architex-config
Key Configuration Sections:
patterns
- Enable/disable and configure architecture patternsnaming
- Customize naming conventions and suffixestemplates
- Configure template engine and stub pathsauto_register
- Automatic service provider registration
๐จ Customizing Templates
Create custom stub files:
- Publish config files:
php artisan vendor:publish --tag=architex-config
-
Customize stub files in
stubs/architex/
-
Available variables in templates:
{{namespace}}
- Class namespace{{class_name}}
- Class name{{interface_name}}
- Interface name{{model_name}}
- Model name{{model_namespace}}
- Model namespace{{layer}}
- Layer name (for DDD){{sub_directory}}
- Subdirectory name (for DDD)
๐ง Auto Registration
The package supports automatic registration of generated classes in service providers:
// config/architex.php 'auto_register' => [ 'enabled' => true, 'providers' => [ 'App\\Providers\\RepositoryServiceProvider', 'App\\Providers\\ServiceServiceProvider', 'App\\Providers\\EventServiceProvider', ], ],
๐ Usage Examples
Repository Pattern with Dependency Injection:
// app/Http/Controllers/UserController.php class UserController extends Controller { public function __construct( private UserRepositoryInterface $userRepository ) {} public function index() { $users = $this->userRepository->all(); return view('users.index', compact('users')); } }
Service Layer:
// app/Http/Controllers/UserController.php class UserController extends Controller { public function __construct( private UserService $userService ) {} public function store(Request $request) { $user = $this->userService->create($request->validated()); return redirect()->route('users.show', $user); } }
CQRS:
// app/Http/Controllers/UserController.php class UserController extends Controller { public function store(CreateUserRequest $request) { $command = new CreateUserCommand( $request->name, $request->email, $request->validated() ); $result = $this->commandBus->dispatch($command); return redirect()->route('users.show', $result); } }
๐ค Contributing
We welcome all contributions! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Create a Pull Request
๐ License
This package is released under the MIT license. See the LICENSE file for more details.
๐งช Testing
Quick Start
# Install dependencies composer install # Run all tests ./run-tests.sh all # Run with coverage ./run-tests.sh coverage # Run specific tests ./run-tests.sh specific tests/ArchitectureGeneratorTest.php
Test Commands
# Run all tests ./vendor/bin/phpunit # Run unit tests only ./run-tests.sh unit # Run integration tests only ./run-tests.sh integration # Run tests in watch mode ./run-tests.sh watch # Run with verbose output ./vendor/bin/phpunit --verbose # Run specific test method ./vendor/bin/phpunit --filter test_can_generate_repository
๐ Documentation
- README.md - Main documentation and usage guide
- DEVELOPMENT.md - Development setup, testing, and contributing guide
- TESTING.md - Detailed testing information
- INSTALLATION_GUIDE.md - Step-by-step installation guide
๐ Support
If you encounter issues or have questions, please:
- Create an issue on GitHub
- Contact us via email: team@laravel-architex.com
- Join our Discord community
Laravel Architex - Help you build Laravel architecture quickly and professionally! ๐