incoder/laravel-ddd

Domain-Driven Design (DDD) Library for Laravel

Maintainers

Package info

github.com/rbsgaridan/laravel-ddd

pkg:composer/incoder/laravel-ddd

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-04-30 09:41 UTC

This package is auto-updated.

Last update: 2026-04-30 09:45:10 UTC


README

Reusable Laravel DDD / Clean Architecture building blocks packaged for Composer.

License PHP Version Laravel Version

Overview

incoder-ddd provides shared foundations for Laravel applications that use a Domain / Application / Infrastructure split. The package includes:

  • base entities and aggregate roots
  • repository abstractions and Eloquent repository bases
  • application service and DTO bases
  • attribute-based route scanning
  • AppService auto-route registration
  • OpenAPI / Swagger generation
  • TypeScript proxy generation
  • Flutter OpenAPI proxy generation
  • SSRS reporting helpers

The package is installable as a standalone Composer library and registers itself through Laravel package auto-discovery.

Developer Manual

For a fuller consumer guide, see docs/DEVELOPER-MANUAL.md.

Package Name

Current composer.json package name:

composer require incoder/laravel-ddd

Requirements

  • PHP ^8.3
  • illuminate/support ^12.21
  • illuminate/database ^12.21
  • ramsey/uuid
  • spatie/laravel-data
  • spatie/laravel-activitylog

Installation

Install the package in a Laravel application:

composer require incoder/laravel-ddd

Laravel will discover Incoder\DDD\Support\IncoderDDDServiceProvider automatically.

Optional publish steps:

php artisan vendor:publish --tag=api-docs
php artisan vendor:publish --tag=incoder-ddd-config

This publishes:

  • config/incoder-ddd.php
  • config/api-docs.php
  • config/reporting.php

What The Package Actually Assumes

Some features are generic. Some are opinionated and default to conventions already encoded in this package.

Those defaults now live in config/incoder-ddd.php.

Default conventions:

  • AppService discovery expects classes under Core\Application\...
  • DI auto-binding expects Core\Domain\... and Core\Infrastructure\Eloquent\Repositories\...
  • controller route scanning reads app/Http/Controllers
  • scaffold commands generate files into core/...
  • AppService HTTP routes are registered under /app/api/{service}

If your application does not follow those conventions, you can override the package defaults in config/incoder-ddd.php. The generic base classes remain reusable even when you disable or replace convention-based scanning.

Core Building Blocks

Domain Entities

Use Entity, AggregateRoot, or AuthenticableAggregateRoot as base classes for domain models.

use Incoder\DDD\Domain\Entities\Entity;
use Incoder\DDD\Support\Attributes\FillableAttribute;

class Department extends Entity
{
    protected $table = 'departments';

    public $incrementing = true;
    protected $keyType = 'int';

    #[FillableAttribute]
    protected string $name;
}

Confirmed behavior from the codebase:

  • soft deletes are enabled on Entity
  • #[FillableAttribute] drives fillable-property detection
  • string keys generate UUIDs on create
  • activity logging is wired through spatie/laravel-activitylog

DTO Base

Incoder\DDD\Application\DTOs\DTOBase extends Spatie\LaravelData\Data and provides toDTO() / toDTOs() helpers for Eloquent models.

Repository Base

Repository contracts extend Incoder\DDD\Domain\Repositories\IRepository. Eloquent implementations can build on:

  • Incoder\DDD\Infrastructure\Repositories\EloquentRepository
  • Incoder\DDD\Infrastructure\Repositories\EloquentRepositoryBase

AppService Base

Incoder\DDD\Application\Services\AppServiceBase provides CRUD-oriented application service helpers and is the base type used by AppService route / OpenAPI / proxy scanning.

The inherited default AppService middleware comes from AppServiceBase:

  • api
  • auth:sanctum

You can override class-wide route middleware with #[AppServiceMiddleware(...)].

Routing

Controller Attribute Routing

#[RouteAttribute] can be used on controller methods. If no middleware is supplied:

  • /api/... and /app/api/... routes default to api
  • other routes default to web

Example:

use Incoder\DDD\Support\Attributes\RouteAttribute;

#[RouteAttribute(methods: ['GET'], uri: '/reports', name: 'reports.index')]
public function index()
{
}

AppService Auto-Routes

Classes that:

  • are in the Composer classmap
  • live under Core\Application\...
  • end with AppService
  • extend AppServiceBase

are auto-registered at boot under /app/api/{service}.

Supported patterns:

  • CRUD conventions: getAll, getPaged, getById, create, update, delete
  • custom routes with #[RouteAttribute]
  • convention routes based on HTTP verb prefixes like getActiveUsers or postArchive

Permission integration is available through #[RequiresPermission(...)] if your app provides a compatible permission middleware alias such as the one from spatie/laravel-permission.

More detail: docs/features/APPSERVICE-ROUTES.md

OpenAPI / Swagger

The package can generate an OpenAPI spec from auto-registered AppServices and exposes Swagger UI in non-production environments when config('api-docs.enabled') is true.

Default routes:

  • UI: /api/docs
  • spec: /api/docs/spec

Generate a spec file:

php artisan api:generate-spec
php artisan api:generate-spec --format=yaml --output=public/api-docs.yaml
php artisan api:generate-spec --stdout

More detail: docs/features/OPENAPI-DOCS.md

Proxy Generation

TypeScript

Generate TypeScript service proxies and DTO/schema models from the discovered AppServices:

php artisan proxy:generate
php artisan proxy:generate --output=resources/js/proxies

Default output path is resources/js/proxies. You can also override it in config/incoder-ddd.php.

Flutter

Generate Flutter/Dart OpenAPI sources via the OpenAPI Generator CLI:

php artisan proxy:generate-flutter \
  --flutter-root=../flutter \
  --output=../flutter/lib/src/generated/openapi \
  --config=../flutter/tool/openapi-generator-config.yaml \
  --jar=../flutter/.tooling/openapi-generator/openapi-generator-cli-7.21.0.jar

The Flutter generator expects:

  • a sibling Flutter project by default
  • Java
  • an OpenAPI Generator CLI JAR at the configured path

Scaffolding Commands

Create a Domain Model Scaffold

php artisan make:domain-model User --type=aggregate --format=string --incrementing=false --schema=admin

Create Model Only

php artisan make:domain-model Employee --type=entity --format=int --incrementing=true --schema=admin --only-model

Create CRUD Around an Existing Model

php artisan make:domain-crud User --schema=admin --format=string --incrementing=false

Important: these commands currently generate into core/... directories and Core\... namespaces in the consuming application.

Reporting

The package includes SSRS reporting support through:

  • Incoder\DDD\Support\Reporting\Contracts\IReportService
  • Incoder\DDD\Support\Reporting\Facades\Report

Supported operations:

  • generatePdfReport()
  • streamPdfReport()
  • getReportInfo()
  • testConnection()

Required environment variables for reporting:

SSRS_BASE_URL=http://your-ssrs-server/ReportServer
SSRS_USERNAME=your_username
SSRS_PASSWORD=your_password
SSRS_TIMEOUT=120
SSRS_CACHE_TTL=0

More detail: docs/features/README-REPORTING.md

Development Notes

  • This repository is a Composer package, not a full Laravel app.
  • Package behavior should remain stable for Composer consumers.
  • If you change command names, config keys, publish tags, route conventions, generated output, or service-provider behavior, treat that as a public API change.

Useful checks:

composer validate --no-check-publish
composer dump-autoload

License

MIT