diff --git a/README.md b/README.md index 84f0419e280a8aca9157729208810bad84dc5aa6..5f5fe10aadeff942f780900851a40f4ef540480c 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,19 @@ microservice_register: `port` (по умолчанию `80`), `scheme` (`http`) и `path_prefix` (`''`) тоже настраиваются здесь же, если сервис вдруг не вписывается в общий шаблон. +### 3a. Документация (Swagger) + +OpenAPI-спека сервиса **всегда** лежит по `/api/docs.json` — маршрут +объявляет сам бандл (`config/docs_routes.php`, подключается тем же импортом +`@MicroserviceRegisterBundle/config/routes.yaml`, см. п. 4), если в +приложении есть nelmio/api-doc-bundle. Свой маршрут на JSON-спеку сервису +заводить не нужно. + +При регистрации бандл отправляет `docs: "/api/docs.json"` — путь внутри +сервиса, как и маршруты. Gateway собирает из этого `/docs`: новый сервис +появляется там сам. Как спека и её пути выглядят снаружи — забота Gateway, +сервис о Gateway ничего не знает. Нет nelmio — нет ни маршрута, ни `docs`. + ### 4. Healthcheck и роутинг бандла Один импорт в `config/routes.yaml` приложения: @@ -141,7 +154,8 @@ php bin/console microservice:register `Service\RegistrationPublisher`, используя `source`/`host` из env, `port`/`scheme`/`path_prefix` из `microservice_register.yaml`, а список маршрутов — `Service\ScopedRouteCollector` (роуты с `#[Scope]`) плюс, - опционально, `microservice_register.routes` из того же конфига. + опционально, `microservice_register.routes` из того же конфига, и путь к + OpenAPI-спеке (`docs`, см. 3a). - Сообщение уходит в топик `microservice-register`; Gateway читает его на своей стороне и обновляет реестр (`Gateway\Microservice\Registry`). - **`Controller\HealthCheckController`** — тот самый `{"status":"Ok"}`, diff --git a/composer.json b/composer.json index 97b331606ef1bca8a3f798bf231ea2511bdae916..455418f8b5cdd030aa8b1e819b11b21686b8fbe0 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "type": "symfony-bundle", "description": "Register microservice in gateway", "license": "MIT", - "version": "1.1.1", + "version": "1.2.0", "authors": [ { "name": "PySTaMbI4", @@ -21,6 +21,9 @@ "symfony/routing": "^7.2 || ^8.0", "symfony/scheduler": "^7.2 || ^8.0" }, + "suggest": { + "nelmio/api-doc-bundle": "The service's OpenAPI spec is served at /api/docs.json and advertised to Gateway" + }, "autoload": { "psr-4": { "RSofts\\Symfony\\Bundle\\Microservice\\Registry\\": "src" diff --git a/config/docs_routes.php b/config/docs_routes.php new file mode 100644 index 0000000000000000000000000000000000000000..5355c1e786d7dc8a55d86d9e474d3103f77bffa9 --- /dev/null +++ b/config/docs_routes.php @@ -0,0 +1,18 @@ +add(RegistrationPublisher::DOCS_ROUTE, RegistrationPublisher::DOCS_PATH) + ->controller('nelmio_api_doc.controller.swagger') + ->methods(['GET']); +}; diff --git a/config/routes.yaml b/config/routes.yaml index 6df6090daad922982da9c5dba74b2182614a36e3..c95281b2cfb1a33b077d659d08507dccbf4288e0 100644 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -1,3 +1,6 @@ microservice_register_health: resource: '../src/Controller/' type: attribute + +microservice_register_docs: + resource: 'docs_routes.php' diff --git a/src/Message/MicroserviceRegisterMessage.php b/src/Message/MicroserviceRegisterMessage.php index dfc90281fa6c906a03b01d3191e96611109256f6..8e7b68b509657fb878a394e1b931d48386a6a942 100755 --- a/src/Message/MicroserviceRegisterMessage.php +++ b/src/Message/MicroserviceRegisterMessage.php @@ -11,7 +11,8 @@ final readonly class MicroserviceRegisterMessage implements JsonSerializable public function __construct( public string $source, public array $connection, - public array $routes + public array $routes, + public ?string $docs = null, ) { } diff --git a/src/Service/RegistrationPublisher.php b/src/Service/RegistrationPublisher.php index bc4e23b03cede324ed6d3032dbd328f50ba03339..1497ad9c67fe4430563d20b2635191634625299e 100644 --- a/src/Service/RegistrationPublisher.php +++ b/src/Service/RegistrationPublisher.php @@ -4,6 +4,7 @@ namespace RSofts\Symfony\Bundle\Microservice\Registry\Service; use RSofts\Symfony\Bundle\Microservice\Registry\Message\MicroserviceRegisterMessage; use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Routing\RouterInterface; /** * The one place that actually builds and sends a registration message — @@ -11,9 +12,17 @@ use Symfony\Component\Messenger\MessageBusInterface; * registration — e.g. from docker-entrypoint.sh at container boot) and * Task\SelfRegisterTick (automatic, every minute, so the entry in Gateway's * registry — TTL-based — doesn't expire between deploys). + * + * Also advertises the service's OpenAPI spec ("docs"): always DOCS_PATH, + * served by this bundle's own route (config/docs_routes.php) whenever the + * app has nelmio/api-doc-bundle. The path is the service's own — like its + * routes, it says nothing about how Gateway exposes it. */ final readonly class RegistrationPublisher { + public const string DOCS_PATH = '/api/docs.json'; + public const string DOCS_ROUTE = 'microservice_register.docs'; + public function __construct( private MessageBusInterface $messageBus, private ScopedRouteCollector $routeCollector, @@ -23,6 +32,7 @@ final readonly class RegistrationPublisher private string $scheme, private string $pathPrefix, private array $routes, + private RouterInterface $router, ) { } @@ -41,6 +51,7 @@ final readonly class RegistrationPublisher // #[Scope] is the preferred way going forward, but nothing here // forces every consuming service to migrate at once. routes: [...$this->routeCollector->collect(), ...$this->routes], + docs: $this->router->getRouteCollection()->get(self::DOCS_ROUTE) !== null ? self::DOCS_PATH : null, )); } }