Автозагрузка API без роутинга

В Metarhia нет app.get('/path', handler). Структура папок api/ автоматически превращается в RPC-интерфейсы и методы.

Идея

applications/myapp/
  api/
    v1/
      warehouse/
        getStock.js
        updateStock.js
      orders/
        create.js

Файл getStock.js автоматически становится методом api.warehouse.getStock версии 1. Никаких декораторов, никакого роутера.

Файл — это метод

// applications/myapp/api/v1/warehouse/getStock.js
module.exports = async ({ itemId }, context) => {
  return await context.lib.db.stock.find(itemId);
};
  • Экспортируется async-функция.
  • Аргументы — структурированный объект (валидируется по metaschema).
  • context — то, что прокинул Impress: сессия, lib, log, db.

Версионирование папкой

api/v1/ и api/v2/ — две версии. Метод вызывается с указанием версии в introspection. Старые клиенты не ломаются.

Клиент строится сам

await app.metacom.load('warehouse');
// Теперь доступно:
await api.warehouse.getStock({ itemId: 42 });

Сервер отдаёт introspection (список интерфейсов и методов) — клиент строит proxy-объект.

Hot reload

Изменили getStock.js — Impress подгрузил новый код в sandbox. Не нужно рестартовать сервер.

Чем это лучше декораторов NestJS

// NestJS — нужен класс, декоратор, регистрация модуля
@Controller('warehouse')
class WarehouseController {
  @Get('stock/:id')
  getStock(@Param('id') id: string) { ... }
}

vs

// Metarhia — просто файл
module.exports = async ({ itemId }) => { ... };
  • Меньше церемонии.
  • Нет привязки к HTTP-методам и URL.
  • Тестируется как обычная функция.

Что взамен Middleware

В Metarhia вместо middleware-цепочки:

  • Перед методом — валидация по metaschema (декларативно).
  • Внутри метода — контекст с lib/log/db инжектится.
  • После метода — единый logger пишет результат и ошибки.

Никаких next, никаких приоритетов, никаких глобальных стейтов.

🎓 Источники

См. также