Vert.x Dynamic API Manager aka Vert-Mock
Небольшой пример на Vert.x 5, показывающий:
- несколько вертикалей (management UI (в планах) + API‑вертикали)
- динамический деплой/undeploy API‑вертикалей по HTTP
- конфигурацию endpoints и HTTP‑ответов через JSON
- health‑endpoint для каждой вертикали
- сохранение состояний деплоев на диск и их восстановление при старте.
- ManagementVerticle.java - control-plane всей системы
- HTTP‑сервер на порту 8080
- маршруты:
- GET /verticles — список активных вертикалей
- POST /verticles/:name/deploy — деплой новой ApiVerticle с config из тела запроса
- PUT /verticles/:name/config — перезапуск вертикали с новым config
- DELETE /verticles/:name — undeploy и удаление конфигурации с диска
- хранит Map<String, String>: имя логической вертикали → deploymentId (TODO: использовать нормальное <K,V> хранилище)
- сохраняет/читает конфиги вертикалей в/из папки ./deployments (по одному JSON‑файлу на вертикаль).
- ApiVerticle.java - базовый актор на соновании которого создаются deployments
- HTTP‑сервер на порту, заданном в config (httpPort)
- динамический набор endpoints из config
- стандартный GET /health, который возвращает JSON с информацией о вертикали (имя, порт, список endpoints, время старта).
- MainVerticle.java - стартер для ManagementVerticle Обе вертикали реализованы через Vert.x 5 VerticleBase и используют Future API (start(): Future, stop(): Future).
Запрос:
POST http://localhost:8080/verticles/api1/deploy
Content-Type: application/jsonТело:
{
"name": "api1",
"httpPort": 8082,
"endpoints": [
{
"path": "/hello",
"method": "GET",
"response": {
"status": 200,
"headers": {
"Content-Type": "text/plain"
},
"body": "Hello from /hello"
}
},
{
"path": "/user",
"method": "GET",
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "{\"id\":1,\"name\":\"John\"}"
}
}
]
}Поля config:
- name — логическое имя вертикали; также используется как имя файла ./deployments/.json
- httpPort — порт HTTP‑сервера этой вертикали
- endpoints — массив описаний endpoint:
- path — путь (например, /hello)
- method — HTTP‑метод (GET, POST, PUT, DELETE)
- response:
- status — HTTP‑код
- headers — объект с заголовками
- body — строка с телом ответа (для JSON — экранированная строка).
Каждая ApiVerticle автоматически добавляет:
GET /health
Content-Type: application/jsonВозвращает JSON вида:
{
"name": "api1",
"port": 8082,
"startedAt": "2026-01-07T10:15:30.123Z",
"endpoints": [
{ "path": "/hello", "method": "GET" },
{ "path": "/user", "method": "GET" }
]
}Информация собирается из конфигурации вертикали (config()), плюс время старта, запомненное при start().
- Папка ./deployments создаётся при старте, если её нет.
- При каждом успешном POST /verticles/:name/deploy:
- config записывается в файл ./deployments/.json.
- При PUT /verticles/:name/config:
- текущая вертикаль name undeploy
- файл ./deployments/.json перезаписывается новым config
- вертикаль name заново деплоится с новым config.
- При DELETE /verticles/:name:
- вертикаль name undeploy
- файл ./deployments/.json удаляется.
При старте приложения:
- Читается список файлов в ./deployments.
- Каждый .json файл:
- читается через Vert.x FileSystem
- парсится в JsonObject
- если есть поле "name" и оно равно имени файла (контроль уникалности при "ручном" создании JSON-ов вертикалей), вертикаль деплоится с этим config.
- Для каждого успешного деплоя логически имя name мапится на deploymentId в памяти.
Требования
- Java 17+
- Maven
- Сборка и запуск собранного пакета
mvn clean package
java -jar target/your-fat-jar.jar- Запуск
mvn compile exec:javaПосле старта:
- Список вертикалей:
curl http://localhost:8080/verticles- Деплой новой вертикали:
curl -X POST http://localhost:8080/verticles/api1/deploy \
-H "Content-Type: application/json" \
-d '{
"name": "api1",
"httpPort": 8082,
"endpoints": [
{
"path": "/hello",
"method": "GET",
"response": {
"status": 200,
"headers": { "Content-Type": "text/plain" },
"body": "Hello!"
}
}
]
}'- Проверка endpoint и health:
curl http://localhost:8082/hello
curl http://localhost:8082/health- Обновление конфигурации:
curl -X PUT http://localhost:8080/verticles/api1/config \
-H "Content-Type: application/json" \
-d '{
"name": "api1",
"httpPort": 8083,
"endpoints": [
{
"path": "/new",
"method": "GET",
"response": {
"status": 200,
"headers": { "Content-Type": "application/json" },
"body": "{\"msg\":\"moved to 8083\"}"
}
}
]
}'- Удаление вертикали:
curl -X DELETE http://localhost:8080/verticles/api1Ограничения и идеи для развития
- Нет management UI (какой-нибудь шаблонизатор, не React)
- Нет аутентификации/авторизации на management API.
- Нет валидации схемы JSON (можно добавить через Vert.x Json Schema).
- Всё хранение — локальные файлы; при кластеризации стоит вынести состояние в общий стор (БД, KV).