Skip to content

Create your first Service

You will create one Client audience boundary inside the current Laravel application, register its provider, and prove the providers can boot.

Generate Client

Run the generator after installing Pulsar.

Context: installed application root — Generate the Client Service.

bash
vendor/bin/pulsar make:service Client
php artisan about

Context: normalized output — The generator reports its location and required provider registration.

txt
Client Service created successfully!
Location: app/Pulsar/Services/Client
Register: App\Pulsar\Services\Client\Providers\ClientServiceProvider::class

Running the same generator again exits 1 and preserves the existing Service.

Context: normalized output — Duplicate Service generation is refused.

txt
Service [Client] already exists!

Inspect the generated boundary

Generatedapp/Pulsar/Services/Client — The exact relevant tree after installation and generation without --web.

txt
app/
├── Providers/
│   └── PulsarServiceProvider.php
└── Pulsar/
    └── Services/
        └── Client/
            ├── Modules/
            │   └── .gitkeep
            ├── Providers/
            │   ├── ClientServiceProvider.php
            │   └── RouteServiceProvider.php
            └── Routes/
                └── api.php
bootstrap/
├── app.php
├── app.php.pulsar.bak
└── providers.php

The files have distinct roles:

Generated file roles
PathRuntime role
app/Providers/PulsarServiceProvider.phpApplication-wide extension point for bindings, Policy naming, gates, and optional observers.
bootstrap/providers.phpLaravel's provider list; it holds the application-wide and Client providers once each.
bootstrap/app.phpApplication builder with Pulsar Listener and Artisan Command discovery paths.
bootstrap/app.php.pulsar.bak{.N}Pre-change recovery copy; never a runtime input.
ClientServiceProvider.phpBoots the Client boundary by registering its route provider.
RouteServiceProvider.phpLoads the API file under /api/client, client. names, and api middleware.
Routes/api.phpEmpty API surface ready for a later feature.
Modules/.gitkeepKeeps the empty Module root in version control; it has no runtime role.

Generatedapp/Pulsar/Services/Client — Checked provider and route excerpts show how the new boundary boots.

php
<?php

namespace App\Pulsar\Services\Client\Providers;

use Illuminate\Support\ServiceProvider;

/**
 * Client Service Provider
 *
 * Responsible for registering and bootstrapping the Client service.
 */
class ClientServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register(): void
    {
        $this->app->register(RouteServiceProvider::class);
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot(): void
    {
        //
    }
}
php
<?php

namespace App\Pulsar\Services\Client\Providers;

use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;

/**
 * Client Route Service Provider
 *
 * Registers API routes with automatic prefix: /api/client
 */
class RouteServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register(): void
    {
        Route::prefix('api/client')
            ->as('client.')
            ->middleware('api')
            ->group(__DIR__ . '/../Routes/api.php');
    }
}
php
<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Client Service Routes
|--------------------------------------------------------------------------
|
| Prefix: /api/client
| Named Routes: client.*
| Middleware: api
|
*/

No web.php exists because --web was not supplied. Only the canonical Service root exists at this checkpoint; do not create empty Domain or Infrastructure directories.

Register and boot

The generator does not modify Laravel's provider list. Add its printed Client class once while keeping the existing application provider and Pulsar's application-wide provider.

bootstrap/providers.php — Keep one entry for each distinct Pulsar provider.

php
<?php

use App\Providers\AppServiceProvider;

return [
    AppServiceProvider::class,
    App\Providers\PulsarServiceProvider::class,
    App\Pulsar\Services\Client\Providers\ClientServiceProvider::class,
];

Context: registered application root — Check that Laravel can boot the registered providers.

bash
vendor/bin/pulsar make:service Client
php artisan about

Successful php artisan about output on the two execution applications reported Laravel v12.65.0 and v13.24.0 with PHP 8.4.21 and Composer 2.9.4. The success condition is application boot, not a route or feature.

Composer's existing App\\ to app/ PSR-4 mapping covers the generated classes. The earlier package install refreshed autoloading, so no autoload refresh is needed. If a customized application has stale autoload state, verify that mapping before treating an autoload refresh as troubleshooting.

What a Service means

A Service is a logical delivery boundary for an audience such as Client, Admin, or Internal inside one Laravel application. It is not a microservice, bounded context, deployment unit, database, or schema. Client is the human-facing audience here. Internal is the usual machine audience for CLI, queue, and scheduler entrypoints, but this tutorial does not generate it.

Continue to Build your first Pulsar feature to add a tested Orders Module and Domain to this registered Service.