Skip to content

ADR-0002: Use SPI for Open Core Architecture

Date: 2026-06-12 Status: Accepted

Context

Mozhno использует модель Open Core: community edition с полной функциональностью + возможность подключения enterprise-расширений (SSO, аудит, биллинг, квоты, вебхуки).

Нужен механизм, позволяющий заменять реализации без форка кодовой базы, с приоритетами и поддержкой нескольких провайдеров одновременно.

Decision

Использован Service Provider Interface (SPI) — набор Java-интерфейсов в модуле mozhno-spi, которые реализуются в mozhno-core (дефолтные реализации) или во внешних JAR-файлах (enterprise-расширения).

Spring автоматически собирает все бины, реализующие SPI-интерфейсы, через List<SPI>. Провайдеры сортируются по priority() и пробуются по цепочке.

Consequences

Позитивные:

  • Zero-cost для community edition: дефолтные реализации всегда доступны.
  • Enterprise-расширения — это обычные Spring-бины в отдельном JAR. Никакой магии с classpath, plugin-системами или OSGi.
  • Приоритеты гарантируют детерминированный порядок: custom-провайдер может перехватить запрос до дефолтного.
  • Тестируемость: каждый SPI можно замокать независимо.

Негативные:

  • Нельзя гарантировать порядок загрузки нескольких enterprise-JAR (решается приоритетами).
  • Сложность отладки: цепочка провайдеров может быть длинной.

Examples

  • AuthenticationProviderSpi — цепочка: JWT → API Key → (SSO/LDAP в enterprise)
  • AuthenticationFlowSpi — логин: password → (Google/SAML в enterprise)
  • QuotaSpi — NoOpQuotaProvider → (Plan-based quota в enterprise)
  • BillingSpi — OpenSourceBillingProvider → (Stripe-based в enterprise)
  • FeatureGateSpi — все фичи включены → (Tier-based gating в enterprise)

Released under the AGPL v3.0 License.