PHPackages                             j0hnys/trident - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. j0hnys/trident

ActiveProject[Framework](/categories/framework)

j0hnys/trident
==============

A laravel package for developing applications following Domain Driven Design (DDD) and Test Driven Design (TDD) principles

v0.3.0.1(6y ago)3792[4 PRs](https://github.com/j0hnys/trident/pulls)MITPHP

Since May 26Pushed 3y agoCompare

[ Source](https://github.com/j0hnys/trident)[ Packagist](https://packagist.org/packages/j0hnys/trident)[ RSS](/packages/j0hnys-trident/feed)WikiDiscussions master Synced 2d ago

READMEChangelogDependencies (16)Versions (14)Used By (0)

trident
=======

[](#trident)

The purpose of this package is to assist developers in building laravel applications using Domain Driven Design (DDD) and Test Driven Development (TDD) principles. The way it is achieved is by creating an application structure through CLI commands that create scaffolding code. Internally the package uses [nikic/PHP-Parser ](https://github.com/nikic/PHP-Parser) in order to understand and edit code.

The main rationale behind this is that the code generated takes care of all the wiring and architecture enforcing that way DDD and TDD principles. This leaves developers more time to focus on implementing business logic.

**video introduction at:**  and

Installation instructions
=========================

[](#installation-instructions)

to add to a laravel project as a package
----------------------------------------

[](#to-add-to-a-laravel-project-as-a-package)

`composer require j0hnys/trident`

to install in laravel
---------------------

[](#to-install-in-laravel)

after executing `php artisan trident:install` add

```
App\Providers\TridentAuthServiceProvider::class,
App\Providers\TridentEventServiceProvider::class,
App\Providers\TridentRouteServiceProvider::class,
App\Providers\TridentServiceProvider::class,

```

to config/app

Application architecture
------------------------

[](#application-architecture)

### Folder structure

[](#folder-structure)

The package on install creates among others the following folder structure

```

|* app
    |- Http
    |- Models
    |- Policies
        |- Trident
    |- Providers
        |->Trident*.php
    |- Trident
        |- Base
        |- Business
            |- Events
            |- Exceptions
            |- Logic
            |- Schemas
            |- Validations
        |- Intefaces
        |- Workflows
            |- Events
            |- Exceptions
            |- Logic
            |- Processes
            |- Repositories
            |- Schemas
            |- Validations

```

Where `|* app` is the app directory of a laravel application.

The goal of this structure is to isolate the Domain Logic from application/infrastructure (as seen on DDD) and at the same time, reuse as many build-in laravel functionality and follow the general philosophy of doing things. This has lead to deviations from a purely DDD approach that simplify some of the structures and flow.

The first deviation is in definitions. There are `Workflows` and `Business`. The Workflows basically implement the workflow of a functionality (e.x. 1. get db list, 2. process, 3. return). The Business implements domain processes (e.x. VAT evaluation, exports to different formats), the concept is to have this functionality isolated and reusable.

The main differences between a pure DDD and the structure above are the following

- Building blocks
    - the "Mappers", "Value Objects", "Factories" are implemented by `StrictTypes` (described below) and eloquent-resources
    - "Entities" are implemented by laravel models and migrations
    - "Services" are implemented by "Workflows" -&gt; "Logic"
    - "Repositories" are implemented as an abstraction above laravel models
    - "Domain Events" are implemented by laravel events
- Layers
    - "Application Layer" is implemented by `app/Http`, `app/Policies` folders basically
    - "Infrastructure Layer" is implemented by laravel
    - "Domain Model Layer" by `app/Trident` folder

For more information about DDD you can reference [this](https://en.wikipedia.org/wiki/Domain-driven_design), [this](https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/ddd-oriented-microservice) and [google](google.com)

Everything inside the `app/Trident` folder is Dependency Injected with Interfaces, the "bind" to laravel happens through dedicated providers in the `app/Providers` folder

The `app/Trident/Business` folder is for implementing domain processes as pure php classes.

The `app/Trident/Workflow/Processes` are for implementing the steps of one workflow process.

---

All the complexity is handled by the package. Using the CLI commands all the necessary objects are created and binded together and to the framework. The developer implementes the functionality needed to the designated places, `Policies` is for authorization, `Events` are for events, `Repositories` are for repositories e.t.c.

### Strict Types

[](#strict-types)

Trident uses [j0hnys/trident-typed](https://github.com/j0hnys/trident-typed) which is a fork of [spatie/typed](https://github.com/spatie/typed) that is tailored for the purpose of Trident.

The main usage is to define strict data structures that are passed through different layers of the architecture.

For example this struct data structure:

```
$developer = new Struct([
    'name' => T::string(),
    'age' => T::int(),
    'second_name' => T::nullable(T::string()),
]);
```

will define an assosiative array that the keys and values have very specific properties. Here the `$developer` can have only "name","age","second\_name" as properties and each property have specific type only (string, int, ?string accordingly).

The code `$developer['name'] = 123;` or `$developer['nameee'] = 'John';` will through an exception.

Basic usage
-----------

[](#basic-usage)

1. `php artisan make:migration create_demo_process`
2. fill in the appropriate data in the migration file
3. `php artisan migrate`
4. `php artisan trident:generate:workflow_restful_crud DemoProcess`

In the end of this process the following will be created:

- a new controller with restful CRUD functions will and placed in `app/Http/Controllers/Trident`
- a new resource in `routes/trident.php` behind the native authentication middleware
- a new model in `app/Models`, a new policy for this process and placed in `app/Policies/Trident`
- a new exception class in `app/Trident/Workflows/Exceptions`
- a new set of validation (FormRequests) and placed in `app/Trident/Workflows/Validations`
- a new set of strict types and placed in `app/Trident/Workflows/Schemas/Logic//Typed`
- a new set of resources and placed in `app/Trident/Workflows/Schemas/Logic//Resources`
- a new repository in `app/Trident/Workflows/Repositories`
- a new logic for this process in `app/Trident/Workflows/Logic`
- finally a new business logic in `app/Trident/Business/Logic`

If we want to add a new function in the process, let's say a new feature we execute:

1. `php artisan trident:generate:workflow_logic_function DemoProcess [function_name]`

which will create automatically the appropriate functions and wiring in the controller, router, workflow logic, business logic, policy, validation. as seen below

Controller:

```
