Skip to main content

Overview

The Laravel OpenAPI Generator does not currently define custom event classes or listeners. The package focuses on direct generation without event-based workflows.
While the package doesn’t dispatch Laravel events, it does provide logging hooks and cache integration points for observability.

Current State

The service provider includes a placeholder method for future event integration: Location: src/Providers/OpenApiGeneratorServiceProvider.php
/**
 * Placeholder for cache clear listener.
 * No event bindings are registered by default.
 */
protected function registerCacheClearListener(): void
{
    // Reserved for future event hooks
}

Logging as Event Alternative

The package uses Laravel’s logging system extensively, which can serve as an observability mechanism.

Logging Channel

All generation activities are logged to the openapi channel:
// config/logging.php
'channels' => [
    'openapi' => [
        'driver' => 'daily',
        'path' => storage_path('logs/openapi.log'),
        'level' => env('LOG_LEVEL', 'debug'),
        'days' => 14,
    ],
],

Logged Activities

The generator logs various activities that could be considered “events”: Route Processing:
Log::channel('openapi')->info('Nwidart modular structure detected', [
    'uri' => $uri,
    'module' => $module,
    'entity' => $entity,
]);
API Type Filtering:
Log::channel('openapi')->info('API type filter set', [
    'types' => $this->apiTypeFilter,
    'available_types' => array_keys(config('openapi.api_types')),
]);
Request Body Generation:
Log::channel('openapi')->info('[buildRequestBody] Using FormRequest/Model data', [
    'source' => $documentation['form_request_class'] ?? 'Model fallback',
    'scenario' => $documentation['scenario'] ?? 'none',
    'fields' => $exampleFields,
]);
Location: src/Services/OpenApiServices.php (multiple occurrences)

Monitoring Generation

You can monitor generation by tailing the log file:
# Watch OpenAPI generation logs
tail -f storage/logs/openapi.log
Example Log Output:
[2026-03-07 10:15:32] local.INFO: API type filter set
{"types":["api","mobile"],"available_types":["api","site","mobile","admin"]}

[2026-03-07 10:15:33] local.INFO: Nwidart modular structure detected
{"uri":"api/security/users","module":"security","entity":"users"}

[2026-03-07 10:15:33] local.INFO: Request name generated
{"uri":"api/security/users","route_name":"security.users.index","module":"security","entity":"users","detected_action":"list","technical_name":"security.users.list","display_name":"[API] security.users.list"}

Cache Hooks

While not events, the cache system provides integration points:

Cache Store

When a specification is generated and cached: Location: src/Services/OpenApiServices.php:110-112
if (config('openapi.cache.enabled')) {
    Cache::put($cacheKey, $result, config('openapi.cache.ttl'));
}

Cache Retrieval

When a cached specification is retrieved: Location: src/Services/OpenApiServices.php:90-95
if ($useCache && config('openapi.cache.enabled')) {
    $cached = Cache::get($cacheKey);
    if ($cached) {
        return $cached; // Cache hit
    }
}

Cache Clearing

When cache is manually cleared: Location: src/Services/OpenApiServices.php:1479-1488
public function clearCache(): void
{
    $patterns = [
        config('openapi.cache.key_prefix') . '*',
    ];

    foreach ($patterns as $pattern) {
        Cache::forget($pattern);
    }
}

Future Event System

If you need event-based workflows, you can implement them in your application.

Custom Event Example

Define an Event:
// app/Events/OpenApiGenerated.php
namespace App\Events;

use Illuminate\Foundation\Events\Dispatchable;

class OpenApiGenerated
{
    use Dispatchable;

    public function __construct(
        public array $spec,
        public array $apiTypes,
        public string $format,
        public float $generationTime
    ) {}
}
Dispatch in Your Code:
use App\Events\OpenApiGenerated;
use Ronu\OpenApiGenerator\Facades\OpenApiGenerator;

$start = microtime(true);
$spec = OpenApiGenerator::generateOpenApi(apiTypes: ['api']);
$time = microtime(true) - $start;

event(new OpenApiGenerated(
    spec: $spec,
    apiTypes: ['api'],
    format: 'openapi',
    generationTime: $time
));
Create a Listener:
// app/Listeners/NotifyTeamOfNewSpec.php
namespace App\Listeners;

use App\Events\OpenApiGenerated;
use Illuminate\Support\Facades\Notification;

class NotifyTeamOfNewSpec
{
    public function handle(OpenApiGenerated $event): void
    {
        // Send Slack notification
        Notification::route('slack', config('services.slack.webhook'))
            ->notify(new SpecGeneratedNotification(
                apiTypes: $event->apiTypes,
                format: $event->format,
                generationTime: $event->generationTime
            ));
    }
}
Register the Listener:
// app/Providers/EventServiceProvider.php
protected $listen = [
    OpenApiGenerated::class => [
        NotifyTeamOfNewSpec::class,
        LogSpecGeneration::class,
    ],
];

Potential Event Points

If the package were to implement events, these would be logical dispatch points:

Before Generation

GenerationStarting::class
Use Cases:
  • Validate configuration
  • Log generation request
  • Clear stale cache

After Generation

GenerationCompleted::class
Use Cases:
  • Store spec to database
  • Upload to CDN or S3
  • Send notifications
  • Update documentation site

Cache Events

CacheHit::class
CacheMiss::class
CacheCleared::class
Use Cases:
  • Monitor cache performance
  • Trigger cache warming
  • Alert on cache misses

Route Discovery

RouteDiscovered::class
Use Cases:
  • Log discovered routes
  • Track API growth
  • Detect new endpoints

Export Events

PostmanExported::class
InsomniaExported::class
Use Cases:
  • Auto-import to collection management
  • Sync with team workspace
  • Trigger CI/CD pipelines

Laravel Event Integration

You can hook into Laravel’s existing events:

Model Events

If you store specs in a database:
use App\Models\ApiSpecification;

ApiSpecification::created(function ($spec) {
    // New spec version created
    event(new SpecVersionCreated($spec));
});

Cache Events

Listen to Laravel’s cache events:
use Illuminate\Support\Facades\Event;
use Illuminate\Cache\Events\CacheHit;
use Illuminate\Cache\Events\CacheMissed;

Event::listen(CacheHit::class, function ($event) {
    if (str_starts_with($event->key, 'openapi_spec_')) {
        // OpenAPI cache hit
        logger()->debug('OpenAPI cache hit', ['key' => $event->key]);
    }
});

Event::listen(CacheMissed::class, function ($event) {
    if (str_starts_with($event->key, 'openapi_spec_')) {
        // OpenAPI cache miss
        logger()->debug('OpenAPI cache miss', ['key' => $event->key]);
    }
});

Observability Patterns

Telescope Integration

If using Laravel Telescope, generation activities are automatically recorded:
  • Cache hits/misses
  • Log entries
  • HTTP requests (if using routes)
  • Command execution (Artisan)
View in Telescope:
http://localhost:8000/telescope/logs
http://localhost:8000/telescope/cache
http://localhost:8000/telescope/commands

Custom Metrics

Track generation metrics:
use Illuminate\Support\Facades\Redis;

class MetricsListener
{
    public function handle(OpenApiGenerated $event): void
    {
        Redis::incr('openapi:generations:total');
        Redis::hincrby('openapi:generations:by_format', $event->format, 1);
        Redis::lpush('openapi:generation_times', $event->generationTime);
    }
}

Webhook Integration

Trigger webhooks after generation:
use Illuminate\Support\Facades\Http;

class WebhookListener
{
    public function handle(OpenApiGenerated $event): void
    {
        Http::post('https://your-app.com/webhooks/openapi-generated', [
            'api_types' => $event->apiTypes,
            'format' => $event->format,
            'path_count' => count($event->spec['paths'] ?? []),
            'generated_at' => now()->toIso8601String(),
        ]);
    }
}

Scheduled Generation

Use Laravel’s scheduler as a time-based “event” system:
// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
    $schedule->command('openapi:generate --all --no-cache')
        ->daily()
        ->onSuccess(function () {
            // Notify team
            event(new DailySpecGenerated());
        })
        ->onFailure(function () {
            // Alert on failure
            event(new SpecGenerationFailed());
        });
}

Public API

Programmatic generation API

Configuration

Configure logging and cache

Logging

Advanced logging configuration

Testing

Test generation workflows