adityapratamaf / laravel-cleanarchitecture-cqrs
Laravel 12 Clean Architecture + CQRS (API + Blade)
Package info
github.com/adityapratamaf/Laravel-CleanArchitecture-CQRS
Type:project
pkg:composer/adityapratamaf/laravel-cleanarchitecture-cqrs
Requires
- php: ^8.2
- laravel/framework: ^12.0
- laravel/sanctum: ^4.3
- laravel/tinker: ^2.10.1
Requires (Dev)
- fakerphp/faker: ^1.23
- laravel/pail: ^1.2.2
- laravel/pint: ^1.24
- laravel/sail: ^1.41
- mockery/mockery: ^1.6
- nunomaduro/collision: ^8.6
- phpunit/phpunit: ^11.5.3
This package is not auto-updated.
Last update: 2026-03-17 15:16:44 UTC
README
# Laravel Clean Architecture + CQRS Starter Template Starter template Laravel 12 yang menggunakan **Clean Architecture + CQRS** dengan struktur yang sederhana, scalable, rapi, dan tidak over-engineered. Template ini dirancang agar bisa digunakan untuk: * REST API * Web UI (Blade) * Proyek menengah sampai terbesar * Starter untuk microservice atau modular monolith * Senior laravel architecture template --- ## ✨ Features * ✅ Laravel 12 * ✅ Clean Architecture * ✅ CQRS Pattern * ✅ DTO-based data transfer * ✅ CommandBus & QueryBus * ✅ Global API Exception Handler * ✅ Support **API** dan **Web Blade** * ✅ Laravel Sanctum Authentication * ✅ Custom Pagination Helper * ✅ Custom Crypto Helper * ✅ Modular folder structure * ✅ Routes berada di `app/Presentation/Routes` * ✅ Views berada di `app/Presentation/Views` * ✅ Contoh module: **User** dan **Product** + migration + seeder * ✅ Create new module with artisan * ✅ Ready for Packagist template usage --- ## 📋 Requirements * PHP `^8.2` * Composer * Database (MySQL/PostgreSQL/SQLite) --- ## 🧠 Clean Architecture & CQRS ### 🏛 Clean Architecture Diperkenalkan oleh **Robert C. Martin (Uncle Bob)**. Tujuan: * Memisahkan business logic dari framework * Meningkatkan testability * Mengurangi ketergantungan pada database & UI * Membuat sistem lebih scalable #### 🔁 Dependency Rule > Dependensi hanya boleh mengarah ke dalam (ke Domain). ```text Framework / DB / UI ↓ Infrastructure ↓ Application ↓ Domain (Core Business) ``` Domain: * Tidak tahu Laravel * Tidak tahu HTTP * Tidak tahu database --- ### ⚡ CQRS Diperkenalkan oleh **Greg Young**. Memisahkan: * ✍ Command → Mengubah state * 📖 Query → Mengambil data Tujuan: * Optimasi read & write * Mengurangi kompleksitas * Memudahkan scaling --- ## 🚌 CommandBus & QueryBus Untuk menghindari tight coupling antara Controller dan Handler, digunakan mediator pattern: * 🚌 CommandBus * 🚌 QueryBus ### 🚌 CommandBus Menangani operasi yang **mengubah state**. Flow: ```text Controller → Command → CommandBus → Handler → Repository → Database ``` Contoh: ```php $command = new CreateUserCommand($name, $email, $password); $this->commandBus->dispatch($command); ``` Karakteristik: * Fokus pada perubahan data * Tidak untuk mengambil data kompleks * 1 Command = 1 Handler --- ### 🚌 QueryBus Menangani operasi **read-only**. Flow: ```text Controller → Query → QueryBus → Handler → Read Model → Response ``` Contoh: ```php $query = new ListUsersQuery($search, $page, $perPage); $result = $this->queryBus->ask($query); ``` Karakteristik: * Tidak mengubah state * Return DTO / array / pagination * Terpisah dari write logic --- ## 🔄 Flow CQRS ### ✍ Write Flow 1. Controller menerima request 2. Validasi via FormRequest 3. Membuat Command 4. Dispatch ke CommandBus 5. Handler memanggil Repository 6. Simpan ke database ### 📖 Read Flow 1. Controller menerima request 2. Membuat Query 3. QueryBus ask ke Handler 4. Handler ambil data 5. Return data + meta pagination --- ## 🧠 Architecture Overview Project ini menggunakan pendekatan **Clean Architecture** dengan pembagian layer berikut: ```text app ├── Domain │ ├── Application │ ├── Shared │ │ └── Bus │ ├── User │ │ ├── DTOs │ │ ├── Commands │ │ └── Queries │ └── Product │ ├── DTOs │ ├── Commands │ └── Queries │ ├── Infrastructure │ ├── Persistence │ │ ├── Eloquent │ │ │ ├── Models │ │ │ └── Repositories │ └── Providers │ ├── Presentation │ ├── Http │ │ ├── Controllers │ │ │ ├── Api │ │ │ └── Web │ │ ├── Requests │ │ └── Resources │ ├── Routes │ │ ├── api.php │ │ └── web.php │ └── Views │ └── Support └── Helpers
🚀 1) Membuat Project dari Nol
1.1 Create Laravel project
composer create-project laravel/laravel Laravel-CleanArchitecture-CQRS-Starter-Template
cd Laravel-CleanArchitecture-CQRS-Starter-Template
1.2 Setup environment
cp .env.example .env php artisan key:generate
1.3 Configure database
Edit .env, contoh MySQL:
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=starter_template DB_USERNAME=root DB_PASSWORD=
🧱 2) Membuat Struktur Clean Architecture + CQRS
Jalankan perintah berikut untuk membuat folder layer dan module:
mkdir -p app/{Domain,Application,Infrastructure,Presentation,Support}
mkdir -p app/Domain/User/{Entities,Contracts}
mkdir -p app/Domain/Product/{Entities,Contracts}
mkdir -p app/Application/Shared/Bus
mkdir -p app/Application/User/{DTOs,Commands,Queries}
mkdir -p app/Application/User/Commands/{CreateUser,UpdateUser,DeleteUser}
mkdir -p app/Application/User/Queries/{GetUserById,ListUsers}
mkdir -p app/Application/Product/{DTOs,Commands,Queries}
mkdir -p app/Application/Product/Commands/{CreateProduct,UpdateProduct,DeleteProduct}
mkdir -p app/Application/Product/Queries/{GetProductById,ListProducts}
mkdir -p app/Infrastructure/Persistence/Eloquent/{Models,Repositories}
mkdir -p app/Infrastructure/Providers
mkdir -p app/Presentation/Routes
mkdir -p app/Presentation/Views/{users,products}
mkdir -p app/Presentation/Http/{Controllers,Requests,Resources}
mkdir -p app/Presentation/Http/Controllers/{Api,Web}
mkdir -p app/Presentation/Http/Requests/{User,Product}
mkdir -p app/Support/Helpers
🛣️ 3) Routing & Views dari app/Presentation
Template ini tidak menggunakan routes/web.php dan routes/api.php default.
Sebagai gantinya:
- ✅ Routes:
app/Presentation/Routes/web.phpdanapp/Presentation/Routes/api.php - ✅ Views:
app/Presentation/Views/...
3.1 Load routes dari app/Presentation/Routes
Edit file: app/Providers/RouteServiceProvider.php
Ubah method boot():
public function boot(): void { $this->routes(function () { \Illuminate\Support\Facades\Route::middleware('api') ->prefix('api') ->group(app_path('Presentation/Routes/api.php')); \Illuminate\Support\Facades\Route::middleware('web') ->group(app_path('Presentation/Routes/web.php')); }); }
3.2 Load views dari app/Presentation/Views
Buat provider:
php artisan make:provider PresentationServiceProvider
Isi app/Infrastructure/Providers/PresentationServiceProvider.php:
<?php namespace App\Infrastructure\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Facades\View; class PresentationServiceProvider extends ServiceProvider { public function boot(): void { View::addLocation(app_path('Presentation/Views')); } }
Daftarkan di config/app.php pada bagian providers:
App\Infrastructure\Providers\PresentationServiceProvider::class,
🚌 4) CQRS Pattern
Project ini menggunakan Command Query Responsibility Segregation (CQRS).
4.1 Command
Command digunakan untuk operasi yang mengubah data.
Contoh:
CreateUserCommand
UpdateUserCommand
DeleteUserCommand
CreateProductCommand
UpdateProductCommand
DeleteProductCommand
Setiap command akan diproses oleh handler terkait, misalnya:
CreateUserCommandHandler
CreateProductCommandHandler
4.2 Query
Query digunakan untuk operasi membaca data.
Contoh:
ListUsersQuery
GetUserByIdQuery
ListProductsQuery
GetProductByIdQuery
Setiap query akan diproses oleh handler terkait, misalnya:
ListUsersQueryHandler
GetProductByIdQueryHandler
4.3 Convention
Convention yang dipakai:
SomeCommand->SomeCommandHandlerSomeQuery->SomeQueryHandler
📦 5) DTO (Data Transfer Object)
DTO digunakan untuk mentransfer data antar layer tanpa bergantung langsung pada request atau model.
Contoh:
CreateUserDTO
UpdateUserDTO
CreateProductDTO
UpdateProductDTO
DTO membantu menjaga layer Application tetap bersih dari framework dependency.
🔄 6) Command Bus & Query Bus
Command dan Query tidak dipanggil langsung.
Controller akan menggunakan:
app/Application/Shared/Bus/CommandBus.phpapp/Application/Shared/Bus/QueryBus.php
Contoh penggunaan:
$commandBus->dispatch(new CreateUserCommand($dto)); $queryBus->ask(new ListUsersQuery());
CQRS bus pada template ini dibuat sederhana, scalable, dan mudah dipahami.
🧰 7) Helpers (Tools reusable)
Letak helper:
app/Support/Helpers/Pagination.php→ meta paginationapp/Support/Helpers/Crypto.php→ encrypt/decrypt string
Helper ini dipakai berulang kali tanpa overengineering.
Contoh helper lain yang bisa dikembangkan:
PaginationLinks
CryptoHelper
ApiResponse
🛡️ 8) API Error Handling
Project ini menggunakan Global Exception Handler untuk API.
Semua error API akan otomatis diformat menjadi struktur yang konsisten.
Contoh server error:
{
"result": false,
"code": 500,
"message": "server error",
"errors": null
}
Contoh validation error:
{
"result": false,
"code": 422,
"message": "validation error",
"errors": {
"email": ["The email field is required"]
}
}
🌐 9) Kenapa API beda dengan Web?
9.1 Web
Di Web UI, controller biasanya menggunakan try-catch.
Tujuannya:
- redirect kembali ke halaman sebelumnya
- mengirim flash message
session('error') - menampilkan alert di Blade
Contoh:
try { $commandBus->dispatch(new CreateProductCommand($dto)); return redirect('/products')->with('success', 'Product created'); } catch (DomainException $e) { return back()->withInput()->with('error', $e->getMessage()); }
Karena web UI perlu memberikan feedback visual ke user.
9.2 API
Pada API, exception tidak perlu ditangkap di controller.
Jika semua exception ditangkap di controller, maka akan menyebabkan:
- code menjadi repetitif
- banyak boilerplate
- response error tidak konsisten
Sebagai gantinya, project ini menggunakan Global Exception Handler.
Controller API cukup fokus pada:
- menerima request
- membuat DTO
- menjalankan command/query
- mengembalikan response sukses
Contoh:
$p = $commandBus->dispatch(new CreateProductCommand($dto)); return response()->json([ 'id' => $p->id, 'name' => $p->name ]);
Jika terjadi error, global handler akan otomatis menangani response JSON.
🗃️ 10) Migrations + Seeders
10.1 Migration users & products
Buat migration jika belum ada:
php artisan make:migration create_products_table
# users table biasanya sudah ada di Laravel default
10.2 Seeder users & products
php artisan make:seeder UserSeeder php artisan make:seeder ProductSeeder
Daftarkan di database/seeders/DatabaseSeeder.php:
public function run(): void { $this->call([ UserSeeder::class, ProductSeeder::class, ]); }
Jalankan migration dan seeder:
php artisan migrate php artisan db:seed
Atau sekaligus fresh + seed:
php artisan migrate:fresh --seed
▶️ 11) Menjalankan Project
Clear cache dan autoload:
composer dump-autoload php artisan optimize:clear
Jalankan server:
php artisan serve
🔐 12) Authentication
API authentication menggunakan Laravel Sanctum.
Login endpoint
POST /api/auth/login
Response contoh:
{
"token_type": "Bearer",
"token": "xxxxxx"
}
Gunakan token pada header:
Authorization: Bearer TOKEN
🌐 13) Endpoint yang tersedia
13.1 Web (Blade)
👤 Users
GET /usersGET /users/createPOST /usersGET /users/{id}GET /users/{id}/editPUT /users/{id}DELETE /users/{id}
📦 Products
GET /productsGET /products/createPOST /productsGET /products/{id}GET /products/{id}/editPUT /products/{id}DELETE /products/{id}
🔑 Auth
GET /loginPOST /logout
13.2 API (JSON)
Base prefix: /api
👤 Users
Dokumentasi Users API tetap dipertahankan dan tidak dihapus.
GET /api/usersPOST /api/usersGET /api/users/{id}PUT /api/users/{id}DELETE /api/users/{id}
📦 Products
GET /api/productsPOST /api/productsGET /api/products/{id}PUT /api/products/{id}DELETE /api/products/{id}
🔐 Auth
POST /api/auth/loginPOST /api/auth/logout
Contoh body JSON create product:
{
"name": "New Product",
"sku": "SKU-NEW-001",
"price": 150000,
"stock": 5,
"description": "test"
}
📘 14) Dokumentasi API Auth + Products (Sanctum)
Base URL:
http://localhost:8000
Kalau kamu pakai domain lain, tinggal ganti.
Catatan: Dokumentasi Users API di atas tetap berlaku dan tidak dihapus. Bagian ini adalah tambahan dokumentasi untuk Auth dan Products dengan Bearer Token.
14.1 Login (ambil token)
Endpoint
POST /api/auth/login
cURL
curl -X POST "http://localhost:8000/api/auth/login" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "email": "admin@example.com", "password": "password123", "device_name": "postman" }'
Response contoh
{
"token_type": "Bearer",
"token": "1|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
Simpan nilai token untuk dipakai di request berikutnya.
14.2 Products (pakai Bearer Token)
Bagian ini berlaku jika route products dimasukkan ke group middleware auth:sanctum.
📄 14.2.1 List products
Endpoint
GET /api/products
cURL
curl -X GET "http://localhost:8000/api/products" \ -H "Accept: application/json" \ -H "Authorization: Bearer 1|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
➕ 14.2.2 Create product
Endpoint
POST /api/products
cURL
curl -X POST "http://localhost:8000/api/products" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer 1|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -d '{ "name": "New Product", "sku": "SKU-N-999", "price": 150000, "stock": 5, "description": "test product" }'
🔍 14.2.3 Show product
Endpoint
GET /api/products/{id}
cURL
curl -X GET "http://localhost:8000/api/products/1" \ -H "Accept: application/json" \ -H "Authorization: Bearer 1|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
✏️ 14.2.4 Update product
Endpoint
PUT /api/products/{id}
cURL
curl -X PUT "http://localhost:8000/api/products/1" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer 1|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -d '{ "name": "Product A Updated", "sku": "SKU-A-001", "price": 175000, "stock": 30, "description": "updated" }'
🗑️ 14.2.5 Delete product
Endpoint
DELETE /api/products/{id}
cURL
curl -X DELETE "http://localhost:8000/api/products/1" \ -H "Accept: application/json" \ -H "Authorization: Bearer 1|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
14.3 Logout (revoke token yang sedang dipakai)
Endpoint
POST /api/auth/logout
cURL
curl -X POST "http://localhost:8000/api/auth/logout" \ -H "Accept: application/json" \ -H "Authorization: Bearer 1|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response contoh
{ "message": "Logged out" }
🧩 15) Cara Menambah Module Baru (Pattern cepat)
Checklist module baru X:
15.1 Domain
app/Domain/X/Entitiesapp/Domain/X/Contracts
15.2 Application
- DTOs:
CreateXDTO,UpdateXDTO,XDTO,PagedXDTO - Commands + Handlers: Create/Update/Delete
- Queries + Handlers: GetById/List
15.3 Infrastructure
- Eloquent model + repository implementation
15.4 Presentation
- Requests: Store/Update
- Controllers: Api + Web
- Routes: tambah di
app/Presentation/Routes/api.phpdanweb.php - Views: tambah di
app/Presentation/Views/x
15.5 Bindings
- bind repository interface → eloquent repository di
CQRSServiceProvider
📦 16) Installation
Clone project:
git clone https://github.com/your-repo/Laravel-CleanArchitecture-CQRS-Starter-Template.git
Install dependency:
composer install
Copy env:
cp .env.example .env
Generate key:
php artisan key:generate
Run migration dan seed:
php artisan migrate --seed
Run server:
php artisan serve
## 🧪 17) Menjalankan Unit Test Project ini sudah siap untuk pengujian menggunakan **PHPUnit / Pest** bawaan Laravel. ### 17.1 Jalankan semua test ```bash php artisan test
atau:
vendor/bin/phpunit
17.2 Jalankan test tertentu
Contoh menjalankan file test tertentu:
php artisan test tests/Feature/ProductTest.php
Atau berdasarkan nama test:
php artisan test --filter=ProductTest
17.3 Jalankan test dengan environment testing
Pastikan file .env.testing sudah disiapkan.
APP_ENV=testing APP_KEY=base64:your-app-key APP_DEBUG=true DB_CONNECTION=pgsql DB_HOST=127.0.0.1 DB_PORT=5432 DB_DATABASE=${DB_SECRET_DATABASE} DB_USERNAME=${DB_SECRET_USERNAME} DB_PASSWORD=${DB_SECRET_PASSWORD}
Generate key
php artisan key:generate --env=testing
Set secret key Database, Username & Password di terminal
export DB_SECRET_DATABASE=YOUR_NAME_DATABASE_TESTING export DB_SECRET_USERNAME=YOUR_USERNAME_DATABASE_TESTING export DB_SECRET_PASSWORD=YOUR_PASSWORD_DATABASE_TESTING
Contoh:
export DB_SECRET_DATABASE=db_project export DB_SECRET_USERNAME=postgres export DB_SECRET_PASSWORD=M3lisaMenariDiMenar@
Check key yang di buat
echo $DB_SECRET_DATABASE echo $DB_SECRET_USERNAME echo $DB_SECRET_PASSWORD
Lalu jalankan:
php artisan test
Laravel akan otomatis memakai environment testing saat test dijalankan.
17.4 Jalankan test setelah migrate fresh
Jika test membutuhkan database yang bersih, gunakan trait seperti:
use Illuminate\Foundation\Testing\RefreshDatabase;
Contoh:
<?php namespace Tests\Feature; use Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; class ProductTest extends TestCase { use RefreshDatabase; public function test_can_list_products(): void { $response = $this->getJson('/api/products'); $response->assertStatus(200); } }
Trait RefreshDatabase akan membantu me-refresh database untuk setiap test agar data tetap konsisten.
17.5 Menjalankan test dengan coverage
Jika environment PHP kamu sudah mendukung coverage (Xdebug atau PCOV), jalankan:
php artisan test --coverage
Atau:
vendor/bin/phpunit --coverage-text
17.6 Rekomendasi struktur test
Untuk menjaga konsistensi dengan Clean Architecture + CQRS, pengujian bisa dipisah menjadi:
tests/Unit→ untuk test DTO, helper, service, handler, dan logic keciltests/Feature→ untuk test endpoint API, controller, auth, dan integrasi flow
Contoh:
tests
├── Unit
│ ├── Helpers
│ ├── DTOs
│ └── Handlers
└── Feature
├── Auth
├── User
└── Product
17.7 Contoh alur testing yang disarankan
Urutan yang umum dipakai saat development:
composer dump-autoload
php artisan optimize:clear
php artisan test
Kalau ingin memastikan database testing benar-benar bersih:
php artisan config:clear
php artisan test
📦 18) Publishing ke Packagist (Create Project)
Agar orang bisa install template ini dengan nama project custom:
composer create-project vendor/laravel-cleanarchitecture-cqrs-starter-template MyProjectName
18.1 composer.json minimal untuk template
Pastikan di root composer.json:
"type": "project""name": "vendor/laravel-cleanarchitecture-cqrs-starter-template"
Contoh:
{
"name": "vendor/laravel-cleanarchitecture-cqrs-starter-template",
"type": "project",
"description": "Laravel 12 Clean Architecture + CQRS starter template (API + Blade)",
"license": "MIT",
"require": {
"php": "^8.2",
"laravel/framework": "^12.0"
},
"autoload": {
"psr-4": {
"App\\": "app/"
}
},
"scripts": {
"post-create-project-cmd": [
"@php artisan key:generate --ansi",
"@php artisan optimize:clear --ansi"
]
}
}
18.2 Steps publish
- Push repository ke GitHub
- Daftarkan repository ke Packagist
- Buat tag release, misalnya
v1.0.0 - Packagist akan auto update
📝 19) Notes
- CQRS di template ini simple & scalable: Command/Query selalu punya Handler dan DTO.
- Tidak menggunakan package CQRS eksternal agar mudah dipahami dan minim dependency.
- Views & routes sengaja dipindah ke
app/Presentationagar konsisten dengan Clean Architecture. - Dokumentasi API Users, Auth Login/Logout, dan Products bisa dipakai sebagai dasar testing di Postman atau cURL.
- Template ini cocok dipakai sebagai base project maupun starter template open source.
📄 20) Artisan Module Generator
make:module adalah custom Artisan command untuk membantu membuat struktur module baru dengan pola:
- Clean Architecture
- CQRS
- DTO
- API Controller
- Web Controller
- Form Request
- Blade Views
Command ini dibuat untuk mempercepat pembuatan module baru tanpa harus membuat folder dan file satu per satu secara manual.
--fields--test--migration- atau tanpa opsi sama sekali
🎯 Tujuan
Generator ini membantu membuat struktur dasar module agar konsisten di seluruh project.
Cocok untuk module seperti:
- Product
- Category
- Brand
- Customer
- Supplier
- Order
Generator ini sengaja dibuat tetap sederhana, supaya:
- mudah dipahami
- mudah diubah
- tidak over-engineering
- tetap scalable untuk project besar
Karena tujuan utama template ini adalah:
- memberikan fondasi arsitektur yang rapi
- mempercepat bootstrap module
- tetap mudah dipahami oleh developer lain
- menghindari generator yang terlalu pintar tapi sulit dirawat
⚙️ Command
Basic
Membuat module tanpa migration, fields, atau test.
php artisan make:module Product
Generator akan membuat:
Domain
Application
Infrastructure
Presentation
tanpa migration dan test.
🧱 Generate Module + Fields
Jika ingin langsung membuat struktur dengan field entity.
php artisan make:module Product \
--fields="name:string,sku:string,price:decimal,stock:int"
Contoh field yang didukung:
| Type | Example |
|---|---|
| string | name:string |
| int | stock:int |
| decimal | price:decimal |
| text | description:text |
| nullable | description:text? |
Nullable menggunakan tanda ?.
Contoh:
description:text?
🧪 Generate Module + Test
Untuk membuat module sekaligus test:
php artisan make:module Product --test
Generator akan membuat:
tests/
├ Feature
│ ├ Api
│ │ └ ProductApiTest.php
│
│ └ Web
│ └ ProductWebTest.php
│
└ Unit
└ Product
└ CreateProductCommandHandlerTest.php
🗄 Generate Module + Migration
Untuk membuat module sekaligus migration:
php artisan make:module Product --migration
File migration akan dibuat di:
database/migrations
Contoh:
create_products_table.php
🚀 Generate Module Lengkap (Recommended)
Module + Fields + Test + Migration:
php artisan make:module Product \
--fields="name:string,sku:string,price:decimal,stock:int" \
--test \
--migration
Ini akan membuat:
Domain
Application
Infrastructure
Presentation
Migration
Feature Test
Unit Test
📁 Struktur yang Dibuat
Contoh struktur setelah generate module Product:
app
├ Domain
│ └ Product
│ ├ Contracts
│ │ └ ProductRepository.php
│ │
│ └ Entities
│ └ Product.php
│
├ Application
│ └ Product
│ ├ DTOs
│ ├ Commands
│ └ Queries
│
├ Infrastructure
│ └ Persistence
│ └ Eloquent
│ ├ Models
│ └ Repositories
│
└ Presentation
├ Http
│ ├ Controllers
│ │ ├ Api
│ │ └ Web
│ │
│ └ Requests
│
├ Routes
│ └ products.php
│
└ Views
└ products
🧠 Tips Penggunaan
Gunakan nama module dalam bentuk singular.
Benar:
php artisan make:module Product
Hindari:
php artisan make:module Products
Karena generator akan otomatis membuat bentuk plural untuk:
- views
- routes
- table migration
🔧 Setelah Generate Module
Setelah module dibuat, lakukan langkah berikut.
1️⃣ Tambahkan Binding Repository
Tambahkan binding di CQRSServiceProvider.
use App\Domain\Product\Contracts\ProductRepository; use App\Infrastructure\Persistence\Eloquent\Repositories\EloquentProductRepository; $this->app->bind( ProductRepository::class, EloquentProductRepository::class );
2️⃣ Tambahkan Routes
Copy route dari:
app/Presentation/Routes/products.php
ke file:
routes/api.php
atau
routes/web.php
3️⃣ Jalankan Migration
Jika menggunakan --migration:
php artisan migrate
4️⃣ Jalankan Test
Jika menggunakan --test:
php artisan test
⚠️ Catatan
Generator ini tidak dimaksudkan menggantikan desain domain.
Gunakan generator sebagai:
- starter structure
- bootstrap module
- template awal
Setelah itu silakan:
- tambah field
- tambah business rule
- tambah validation
- tambah logic domain
sesuai kebutuhan project.
🧩 Filosofi Template Ini
Template ini dibuat dengan prinsip:
- Clean Architecture
- CQRS
- Explicit DTO
- Simple Repository Pattern
- No Magic
Dengan tujuan:
- mudah dipahami
- mudah di-scale
- mudah dirawat
- tidak over-engineered
📄 21) License
MIT License © 2026 Aditya Pratama Febriono This project is open-sourced software licensed under the MIT license.