Skip to content
Jean-Marc Strauven edited this page Dec 23, 2025 · 1 revision

Events

Learn about the events dispatched by Laravel ApiRoute and how to listen to them.


Overview

Laravel ApiRoute dispatches events at key points in the API lifecycle:

Event When Dispatched
DeprecatedVersionAccessed When a deprecated version is accessed
VersionDeprecated When a version is marked as deprecated
VersionSunset When a version is marked as sunset
VersionCreated When a new version is created

DeprecatedVersionAccessed

Dispatched every time a deprecated version is accessed.

Event Class

<?php

namespace Grazulex\ApiRoute\Events;

use Grazulex\ApiRoute\VersionDefinition;
use Illuminate\Http\Request;

final readonly class DeprecatedVersionAccessed
{
    public function __construct(
        public VersionDefinition $version,
        public Request $request
    ) {}
}

Properties

Property Type Description
$version VersionDefinition The deprecated version
$request Request The incoming HTTP request

Use Cases

  • Log deprecated version usage
  • Track which clients still use deprecated versions
  • Alert developers about high deprecated usage

Example Listener

<?php

namespace App\Listeners;

use Grazulex\ApiRoute\Events\DeprecatedVersionAccessed;
use Illuminate\Support\Facades\Log;

class LogDeprecatedVersionUsage
{
    public function handle(DeprecatedVersionAccessed $event): void
    {
        Log::warning('Deprecated API version accessed', [
            'version' => $event->version->name(),
            'endpoint' => $event->request->path(),
            'method' => $event->request->method(),
            'ip' => $event->request->ip(),
            'user_agent' => $event->request->userAgent(),
            'user_id' => $event->request->user()?->id,
        ]);
    }
}

VersionDeprecated

Dispatched when a version is programmatically marked as deprecated.

Event Class

<?php

namespace Grazulex\ApiRoute\Events;

use Grazulex\ApiRoute\VersionDefinition;

final readonly class VersionDeprecated
{
    public function __construct(
        public VersionDefinition $version
    ) {}
}

Use Cases

  • Send notifications to API consumers
  • Update documentation
  • Log for audit trail

Example Listener

<?php

namespace App\Listeners;

use Grazulex\ApiRoute\Events\VersionDeprecated;
use App\Notifications\ApiVersionDeprecated;
use App\Models\ApiConsumer;

class NotifyApiConsumers
{
    public function handle(VersionDeprecated $event): void
    {
        $consumers = ApiConsumer::where('api_version', $event->version->name())->get();

        foreach ($consumers as $consumer) {
            $consumer->notify(new ApiVersionDeprecated(
                $event->version->name(),
                $event->version->deprecationDate(),
                $event->version->sunsetDate(),
                $event->version->successor()
            ));
        }
    }
}

VersionSunset

Dispatched when a version is marked as sunset (end-of-life).

Event Class

<?php

namespace Grazulex\ApiRoute\Events;

use Grazulex\ApiRoute\VersionDefinition;

final readonly class VersionSunset
{
    public function __construct(
        public VersionDefinition $version
    ) {}
}

Use Cases

  • Archive version resources
  • Send final notifications
  • Update documentation

Example Listener

<?php

namespace App\Listeners;

use Grazulex\ApiRoute\Events\VersionSunset;
use Illuminate\Support\Facades\Storage;

class ArchiveVersionResources
{
    public function handle(VersionSunset $event): void
    {
        $version = $event->version->name();

        // Archive controllers
        $sourcePath = app_path("Http/Controllers/Api/{$version}");
        $archivePath = storage_path("archived/api/{$version}");

        if (is_dir($sourcePath)) {
            // Move to archive
            rename($sourcePath, $archivePath);
        }

        // Log the archival
        Log::info("API version {$version} has been archived", [
            'sunset_date' => $event->version->sunsetDate(),
        ]);
    }
}

VersionCreated

Dispatched when a new version is created via Artisan command.

Event Class

<?php

namespace Grazulex\ApiRoute\Events;

use Grazulex\ApiRoute\VersionDefinition;

final readonly class VersionCreated
{
    public function __construct(
        public VersionDefinition $version
    ) {}
}

Use Cases

  • Set up monitoring for new version
  • Initialize documentation
  • Send team notifications

Registering Listeners

Using EventServiceProvider

<?php

namespace App\Providers;

use Grazulex\ApiRoute\Events\DeprecatedVersionAccessed;
use Grazulex\ApiRoute\Events\VersionDeprecated;
use Grazulex\ApiRoute\Events\VersionSunset;
use Grazulex\ApiRoute\Events\VersionCreated;
use App\Listeners\LogDeprecatedVersionUsage;
use App\Listeners\NotifyApiConsumers;
use App\Listeners\ArchiveVersionResources;
use App\Listeners\SetupNewVersion;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        DeprecatedVersionAccessed::class => [
            LogDeprecatedVersionUsage::class,
        ],
        VersionDeprecated::class => [
            NotifyApiConsumers::class,
        ],
        VersionSunset::class => [
            ArchiveVersionResources::class,
        ],
        VersionCreated::class => [
            SetupNewVersion::class,
        ],
    ];
}

Using Closures

use Illuminate\Support\Facades\Event;
use Grazulex\ApiRoute\Events\DeprecatedVersionAccessed;

Event::listen(DeprecatedVersionAccessed::class, function ($event) {
    Log::warning("Deprecated version {$event->version->name()} accessed");
});

Queued Listeners

For performance, queue non-critical event handling:

<?php

namespace App\Listeners;

use Grazulex\ApiRoute\Events\DeprecatedVersionAccessed;
use Illuminate\Contracts\Queue\ShouldQueue;

class LogDeprecatedVersionUsage implements ShouldQueue
{
    public $queue = 'api-analytics';

    public function handle(DeprecatedVersionAccessed $event): void
    {
        // Heavy processing happens in queue
    }
}

Custom Events

Dispatch your own events based on version checks:

use Grazulex\ApiRoute\Facades\ApiRoute;

class ApiMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        $version = $request->apiVersion();
        $definition = $request->apiVersionDefinition();

        // Custom event for beta usage
        if ($definition->isBeta()) {
            event(new BetaVersionAccessed($definition, $request));
        }

        // Custom event for specific client
        if ($request->header('X-Client-Id') === 'legacy-app') {
            event(new LegacyClientRequest($version, $request));
        }

        return $next($request);
    }
}

Notifications Example

Slack Notification for Deprecated Usage

<?php

namespace App\Notifications;

use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\SlackMessage;

class HighDeprecatedUsageAlert extends Notification
{
    public function __construct(
        private string $version,
        private float $percentage
    ) {}

    public function via($notifiable): array
    {
        return ['slack'];
    }

    public function toSlack($notifiable): SlackMessage
    {
        return (new SlackMessage)
            ->warning()
            ->content("High deprecated API usage detected!")
            ->attachment(function ($attachment) {
                $attachment
                    ->title("API Version: {$this->version}")
                    ->fields([
                        'Usage' => "{$this->percentage}% of total traffic",
                        'Action Required' => 'Review migration timeline',
                    ]);
            });
    }
}

Testing Events

Assert Event Dispatched

use Grazulex\ApiRoute\Events\DeprecatedVersionAccessed;
use Illuminate\Support\Facades\Event;

test('deprecated version access dispatches event', function () {
    Event::fake([DeprecatedVersionAccessed::class]);

    $response = $this->get('/api/v1/users');

    Event::assertDispatched(DeprecatedVersionAccessed::class, function ($event) {
        return $event->version->name() === 'v1';
    });
});

Assert Listener Called

use App\Listeners\LogDeprecatedVersionUsage;
use Grazulex\ApiRoute\Events\DeprecatedVersionAccessed;

test('deprecated access is logged', function () {
    $listener = new LogDeprecatedVersionUsage();

    $event = new DeprecatedVersionAccessed(
        $this->createDeprecatedVersion(),
        Request::create('/api/v1/users')
    );

    Log::shouldReceive('warning')
        ->once()
        ->withArgs(function ($message, $context) {
            return str_contains($message, 'Deprecated');
        });

    $listener->handle($event);
});

Next Steps

Clone this wiki locally