Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Starter Laravel Package

laravel-ddd/starter

Composer starter kit that turns a fresh Laravel 12/13 app into a Domain-Driven Design structure. Includes base Entity/ValueObject/Repository/Service classes, 12 generators, interactive installer (auth, docs, tests, sample module), API-ready routes, and optional AI context.

View on GitHub
Deep Wiki
Context7
## Getting Started

1. **Installation**:
   ```bash
   composer create-project laravel/laravel my-project
   cd my-project
   composer require laravel-ddd/starter
   php artisan ddd:install

Follow the interactive prompts to configure auth, sample modules, and testing.

  1. First Use Case: Create a module for your first domain (e.g., Products):

    php artisan ddd:make-module Products
    

    This generates a complete module structure with entities, repositories, services, and tests.

  2. Key Files to Explore:

    • app/Domains/ – Module organization
    • routes/domains/ – Domain-specific routes
    • config/ddd.php – Package configuration

Implementation Patterns

1. Module Creation Workflow

  • Start with ddd:make-module for a new domain (e.g., Orders).
  • Use ddd:make-entity for domain-specific entities (e.g., Order, OrderItem).
  • Generate repositories (ddd:make-repository) and services (ddd:make-service) to encapsulate business logic.
  • Create thin controllers (ddd:make-controller) that delegate to services.

Example:

php artisan ddd:make-module Orders
php artisan ddd:make-entity Order Orders --migration --model
php artisan ddd:make-service OrderService Orders
php artisan ddd:make-repository OrderRepository Orders --eloquent
php artisan ddd:make-controller OrderController Orders

2. Domain-Driven Design Patterns

  • Entities: Use Entity base class for objects with identity (e.g., User, Product).
    class User extends Entity {
        public function getEmail(): Email { ... }
    }
    
  • Value Objects: Use ValueObject for immutable data (e.g., Email, Price).
    class Email extends ValueObject {
        public function __construct(protected string $value) { ... }
    }
    
  • Repositories: Implement RepositoryInterface for data access abstraction.
    class EloquentOrderRepository implements OrderRepositoryInterface { ... }
    
  • Services: Orchestrate domain logic using repositories.
    class OrderService extends Service {
        public function createOrder(OrderData $data) { ... }
    }
    

3. Testing Integration

  • Tests are auto-generated with each command (PHPUnit/Pest).
  • Unit tests live in Domains/[Module]/Tests/Unit/.
  • Feature tests live in Domains/[Module]/Tests/Feature/.
  • Run tests for a module:
    php artisan test --filter=Orders
    

4. API Development

  • Generate API resources (ddd:make-resource) for JSON serialization.
  • Use ddd:make-request for validation logic.
  • Domain-specific routes are auto-generated in routes/domains/[Module].php.
  • Include routes in routes/api.php:
    require app_path('Domains/Orders/Routes/Orders.php');
    

5. Dependency Injection

  • Services and repositories are injected into controllers via Laravel’s container.
  • Example controller:
    class OrderController extends Controller {
        public function store(Request $request, OrderService $service) {
            $order = $service->create($request->validated());
            return response()->json(['data' => $order], 201);
        }
    }
    

6. Migration and Database

  • Migrations are generated alongside entities (--migration flag).
  • Eloquent models are placed in app/Models/ (separate from domain logic).
  • Run migrations:
    php artisan migrate
    

Gotchas and Tips

Pitfalls

  1. Namespace Conflicts:

    • Ensure module names are unique to avoid namespace collisions (e.g., Domains/Users/Entities/User vs. Domains/Admins/Entities/User).
    • Fix: Use descriptive module names (e.g., CustomerManagement instead of Users).
  2. Test Generation Overrides:

    • If tests are not generating, check config/ddd.php for generate_tests and test_package settings.
    • Fix:
      php artisan vendor:publish --tag=ddd-config
      
      Then update the config and regenerate components.
  3. Route Caching:

    • After adding new domain routes, clear the route cache:
      php artisan route:clear
      
  4. Eloquent Model Placement:

    • Eloquent models are created in app/Models/ by default, which may feel out of place in a DDD structure.
    • Tip: Override the stubs or manually move models to Domains/[Module]/Infrastructure/Persistence/Models/.
  5. Service Provider Registration:

    • Module service providers are auto-generated but must be registered in config/app.php.
    • Tip: Use php artisan ddd:list to verify all providers are listed.
  6. Interactive Installer Quirks:

    • If the installer hangs, ensure you’re in a fresh Laravel project (no existing app/Domains/).
    • Fix: Delete the app/Domains/ directory and rerun ddd:install.

Debugging Tips

  1. Command Issues:

    • Check if the package is properly installed:
      composer show laravel-ddd/starter
      
    • Reinstall if needed:
      composer require laravel-ddd/starter --dev
      
  2. Stub Customization:

    • Stubs are located in vendor/laravel-ddd/starter/src/stubs/.
    • Override them by publishing the package’s assets:
      php artisan vendor:publish --tag=ddd-stubs --force
      
    • Customize stubs in resources/stubs/.
  3. AI Agent Context:

    • The AGENTS.md file is optional but useful for AI-assisted development.
    • Tip: Include it in your project’s root for context:
      curl -o AGENTS.md https://raw.githubusercontent.com/MMoza/laravel-ddd/main/agents/AGENTS.md
      

Extension Points

  1. Custom Base Classes:

    • Extend the base classes (Entity, ValueObject, etc.) in app/Domains/Base/.
    • Example: Add soft deletes to Entity:
      namespace App\Domains\Base;
      use Illuminate\Database\Eloquent\SoftDeletes;
      class Entity extends \Illuminate\Database\Eloquent\Model {
          use SoftDeletes;
          // ...
      }
      
  2. Additional Artisan Commands:

    • Create custom commands in app/Console/Commands/ to extend DDD functionality.
    • Example: Add a command to generate domain events:
      php artisan make:command Ddd:Make:Event
      
  3. Domain Events:

    • Integrate events by creating an Events/ directory in each module.
    • Example:
      php artisan ddd:make-event OrderCreated Orders
      
  4. Policy Integration:

    • Add policies to Domains/[Module]/Policies/ and register them in the module’s service provider.
    • Example:
      Gate::resource('orders', Order::class, OrderPolicy::class);
      

Performance Tips

  1. Eager Loading:

    • Use repositories to eager load relationships to avoid N+1 queries.
    • Example:
      $repository->with(['items.product'])->find($id);
      
  2. Caching:

    • Cache repository results for read-heavy operations:
      $repository->remember(60, function () { ... });
      
  3. Batch Processing:

    • Use repositories to batch operations (e.g., bulk updates):
      $repository->update([1, 2, 3], ['status' => 'processed']);
      

Best Practices

  1. Keep Controllers Thin:

    • Controllers should only handle HTTP concerns (validation, routing) and delegate to services.
    • Anti-pattern:
      // Bad: Business logic in controller
      public function update(Request $request) {
          $user = User::find($request->id);
          $user->update($request->all());
      }
      
    • Good:
      // Controller delegates to service
      public function update(Request $request, UserService $service) {
          $service->update($request->id, $request->validated());
      }
      
  2. Use Value Objects for Primitive Obsession:

    • Replace primitive types (e.g., string, int) with value objects (e.g., Email, Money).
    • Example:
      class Money extends ValueObject {
          public function __construct(public int $amount, public string $currency) {}
      }
      
  3. Domain Events for Side Effects:

    • Use events to trigger side effects (e.g., notifications, analytics) without coupling services
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor