REPOSITORY / ScuroNeko/Laniakea

Wiki

KNOWLEDGE REPOSITORY
3
Middleware RU
ScuroNeko edited this page 2026-05-20 13:19:27 +03:00

Middleware RU

English version: Middleware

Это краткая русскоязычная версия страницы про middleware. Полная и наиболее актуальная страница: Middleware.

Зачем нужен middleware

Middleware позволяет запускать логику до обработчиков команд, данных callback и обновлений.

Это главное место для сквозной логики:

  • проверки доступа;
  • журналирование запросов;
  • feature flags;
  • простая подготовка контекста;
  • side effects вроде analytics.

Уровни middleware

Есть три уровня:

  • на уровне бота через Bot.AddMiddleware(...);
  • на уровне плагина через Plugin.AddMiddleware(...);
  • на уровне команды или callback через Command.Use(...).

Их удобно понимать так:

  • уровень бота действует на весь бот;
  • уровень плагина на один плагин;
  • уровень команды на одну конкретную команду или данные callback.

Порядок выполнения

Для команд и данных callback порядок такой:

  1. middleware бота;
  2. middleware плагина;
  3. middleware команды или callback;
  4. финальный обработчик.

Для обработчиков обновлений:

  1. middleware бота;
  2. middleware плагина для каждого подходящего плагина;
  3. обработчик обновления.

Synchronous middleware

Сигнатура:

func(ctx *laniakea.MessageContext, db T) bool

Возвращает:

  • true — продолжать;
  • false — остановить текущую цепочку.

Это правильный вариант для:

  • контроля доступа;
  • обязательной валидации;
  • ограничителей частоты;
  • любой логики, которая должна уметь реально остановить цепочку обработки.

Asynchronous middleware

Можно включить SetAsync(true).

Но это меняет семантику:

  • middleware идет в goroutine;
  • выполнение цепочки продолжается сразу;
  • возвращаемое значение bool игнорируется;
  • middleware получает копию MessageContext.

Поэтому async middleware подходит только для:

  • телеметрии;
  • аудиторских логов;
  • уведомлений без ожидания результата;
  • best-effort side effects.

Он не подходит для:

  • проверок доступа;
  • обязательной валидации;
  • логики, которая должна переписать ctx и повлиять на обработчик.

Почему async middleware получает копию MessageContext

Так библиотека избегает очевидных гонок данных между goroutine middleware и основной цепочкой обработки.

Практический вывод:

  • изменения ctx внутри async middleware не становятся каноническим контекстом для обработчика;
  • async middleware не может надежно остановить поток выполнения.

Порядок

Только middleware уровня бота имеет явную сортировку:

  • сначала по order;
  • потом по name.

Middleware уровня плагина и команды сохраняют порядок добавления.

Частые ошибки

  • Использовать async middleware для блокировки доступа.
  • Надеяться, что async middleware сможет изменить ctx.Text для обработчика.
  • Настраивать middleware плагина после AddPlugins(...).
  • Оставлять middleware без внятного имени.

Что читать дальше