Signal — це PHP-бібліотека від Стіва МакДугалла, яка зчитує атрибути у ваших класах та методах для автоматичної генерації документації. Основна ідея в тому, щоб тримати API-референси поруч із кодом: так документація оновлюється разом із ним, а не застаріває в окремих файлах. Інструмент потребує PHP 8.5 та Symfony Console і поширюється за ліцензією MIT.
Пакет пропонує 24 атрибути, розділені на три групи: роль класу в системі, його зв’язки та статус, а також опис окремих методів. Ви анотуєте код, запускаєте команду і отримуєте Markdown для читання або JSON для подальшої обробки інструментами.
# Визначення ролі класу
Перша група атрибутів описує архітектурну роль класу. До списку з 13 елементів увійшли базові блоки: #[Module], #[Service], #[Repository], #[Action], #[Controller], #[Event], #[Listener], #[Middleware], #[Job], #[Command], #[Query], #[Aggregate] та #[ValueObject]. Кожен із них підтримує необов'язковий опис та список тегів:
use JustSteveKing\Signal\Attributes\Service;
#[Service(
description: 'Issues and revokes API tokens for authenticated users',
tags: ['auth', 'tokens'],
)]
final class TokenService
{
// ...
}
Під час генерації Signal групує класи за цими типами: усі контролери потрапляють в один розділ, сервіси — в інший.
# Зв’язки та статус
Друга група фіксує взаємодію класу з іншими частинами системи та його поточний стан. #[DependsOn] вказує на залежність, #[ListensTo] пов’язує слухача з подією, а #[Deprecated] та #[Internal] позначають класи, з якими розробникам слід бути обережними:
use JustSteveKing\Signal\Attributes\Listener;
use JustSteveKing\Signal\Attributes\ListensTo;
use JustSteveKing\Signal\Attributes\DependsOn;
#[Listener(description: 'Sends a welcome email after registration')]
#[ListensTo(event: UserRegistered::class)]
#[DependsOn(class: MailService::class)]
final class SendWelcomeEmail
{
// ...
}
Такі деталі зазвичай або тримають у голові, або малюють на діаграмах, які ніхто не оновлює. Атрибути безпосередньо в коді допомагають підтримувати актуальність знань про систему.
# Документування методів
Третя група описує логіку роботи методів. #[Route] містить HTTP-метод та шлях, #[Authorize] вказує на необхідні права доступу, #[Validates] описує правила валідації полів, а #[Cached] — час життя кешу (TTL). Ще три атрибути розкривають поведінку, яку неможливо зрозуміти лише з сигнатури методу: #[Emits] для подій, що запускаються, #[Throws] для можливих винятків та #[SideEffect] для побічних дій (наприклад, надсилання листа чи запис у чергу).
use JustSteveKing\Signal\Attributes\Route;
use JustSteveKing\Signal\Attributes\Authorize;
use JustSteveKing\Signal\Attributes\Validates;
use JustSteveKing\Signal\Attributes\Emits;
use JustSteveKing\Signal\Attributes\Throws;
use JustSteveKing\Signal\Attributes\SideEffect;
#[Route(method: 'POST', path: '/api/subscriptions', description: 'Start a subscription')]
#[Authorize(ability: 'subscriptions.create')]
#[Validates(field: 'plan', rules: 'required|in:monthly,yearly')]
#[Emits(event: 'SubscriptionStarted')]
#[SideEffect(description: 'Charges the customer through the payment gateway', tags: ['billing'])]
#[Throws(exception: PaymentFailedException::class, description: 'If the gateway rejects the charge')]
public function store(Request $request): JsonResponse
{
// ...
}
Атрибути #[SideEffect] та #[Throws] особливо корисні, адже вони документують те, що неможливо вирахувати за типом поверненого значення. Інформація про те, що метод списує кошти з картки або може видати PaymentFailedException, зазвичай спливає лише тоді, коли щось іде не так.
# Налаштування та вивід
Signal використовує конфігураційний файл signal.json у корені проєкту. У ньому ви вказуєте директорії для сканування, формати виводу, шляхи збереження та папки, які варто ігнорувати:
{
"input": "src/",
"output": {
"format": ["markdown", "json"],
"path": "docs/"
},
"exclude": [
"src/Attributes/"
]
}
Після налаштування документація генерується однією командою:
php vendor/bin/signal generate
Результат у Markdown містить зміст та групування за типами класів. JSON-файл із тими ж метаданими можна використовувати для генерації OpenAPI-специфікацій або внутрішніх каталогів сервісів.
Встановити бібліотеку можна через Composer:
composer require juststeveking/signal
Вихідний код та повний список атрибутів доступні на GitHub.