Getting Started

Quick Start

Convert a fresh Laravel project to layers, create your first layer and check its boundaries, in five minutes.

This guide starts from a fresh Laravel project. On an application with code to keep, read Existing application instead.

Create the project

composer create-project laravel/laravel my-app
cd my-app
composer require lomkit/laravel-osdd

Convert it to layers

php artisan osdd:start

The command asks for confirmation, then:

  1. creates the functional/users layer: the User model, its factory, seeder and migration, and a provider that points Laravel's auth to that model;
  2. creates the technical/osdd layer: the OSDD configuration, the cache and jobs migrations, and LayersSeeder as the default seeder of db:seed;
  3. registers both layers in the root composer.json and removes the App\Providers\... entries from bootstrap/providers.php;
  4. deletes app/ and config/, empties database/ except database/database.sqlite;
  5. asks to run composer update functional/users technical/osdd.
functional/
  users/
    composer.json
    src/Models/User.php
    src/Providers/UsersServiceProvider.php
    database/factories/UserFactory.php
    database/migrations/0001_01_01_000000_create_users_table.php
    database/seeders/UsersSeeder.php
technical/
  osdd/
    composer.json
    config/osdd.php
    database/migrations/
    src/Providers/OsddServiceProvider.php
database/
  database.sqlite

Create the tables:

php artisan migrate
In a script or a CI job: php artisan osdd:start --force --composer-update. See osdd:start for every detail.

Create your first layer

php artisan osdd:layer

The command asks where to create the layer (functional or technical), its name (orders) and which files to generate. The default selection creates a migration, a model, a factory, a service provider and a test. Then it registers functional/orders in the root composer.json and offers to run composer update functional/orders.

functional/orders/
├── composer.json
├── src/
│   ├── Models/Order.php
│   └── Providers/OrdersServiceProvider.php
├── database/
│   ├── factories/OrderFactory.php
│   └── migrations/xxxx_xx_xx_xxxxxx_create_orders_table.php
└── tests/
    └── Feature/OrdersTest.php

Without a terminal, name the layer and pick the generators:

php artisan osdd:layer functional/orders --generators=migration,model,factory,provider,test --composer-update

Generate code inside it

Every make:* command has an osdd:* twin that takes a --layer option:

php artisan osdd:controller OrderController --layer=functional/orders

The controller lands in functional/orders/src/Http/Controllers, not in app/. --layer=orders works too while no other layer is named orders.

Run it

php artisan migrate        # every layer's migrations
php artisan osdd:seed      # every layer's seeders
php artisan osdd:phpunit   # one test suite per layer in phpunit.xml
php artisan test

Keep the boundaries

A layer declares the layers it uses. For a new layer, pass --requires:

php artisan osdd:layer functional/invoices --requires=functional/orders

Then check that every layer only uses the layers it requires:

php artisan osdd:check
  ERROR  functional/orders uses functional/billing but does not require it.

  functional/orders/src/Checkout.php:7 ............ Functional\Billing\Models\Invoice

Next steps

  • Layers explains what makes a folder a layer.
  • Add a domain takes a layer from empty to a tested CRUD resource.
  • Tests and CI runs osdd:check on every pull request.