Skip to content

SDK Overview

можно SDKs use local evaluation to deliver flag values with minimal latency. Rule sets are fetched once from the server and evaluated locally in your application process — no network round-trip per flag check.

Architecture

flowchart TD
    subgraph Your Application
        SDK[Mozhno SDK Client]
        Cache[In-Memory Rule Cache]
        Eval[Local Evaluator]
    end

    subgraph Mozhno Server
        API[REST API]
        DB[(PostgreSQL)]
    end

    SDK -->|1. Fetch rules on init| API
    API -->|2. Return flags + rules| SDK
    SDK -->|3. Store in memory| Cache

    App[Application Code] -->|isEnabled| Eval
    Eval -->|Read rules| Cache
    Eval -->|Evaluate against context| Eval
    Eval -->|Return value| App

    SDK -->|Background polling| API
    API -->|Updated flags (ETag)| SDK
    SDK -->|Refresh| Cache

How Local Evaluation Works

  1. Initialisation: The SDK connects to the можно server and downloads all flag rules and targeting configurations for the environment associated with your API key.
  2. Caching: Rules are stored in an in-memory cache within your application process.
  3. Evaluation: When your code calls isEnabled(), the SDK evaluates the rules locally against the provided context. No network call is made.
  4. Background Sync: The SDK periodically polls the server for rule updates. Uses If-None-Match / ETag for efficient delta detection.

Tip: Local evaluation means flag checks are sub-millisecond and work even during temporary network disruptions. The SDK always falls back to the last known rule set.

Evaluation Logic

The SDK evaluates flags in this order:

  1. Flag disabled?false
  2. No activation/strategy?true
  3. Constraints (AND): all attribute rules must match the context
  4. Segments (OR): at least one segment must match
  5. Both present: either constraints or segments passing grants access (OR)
  6. Percentage rollout: MurmurHash32 over flagKey + (userId || sessionId), compared against configured percentage
  7. Nothing matchedfalse

Supported Operators

OperatorDescription
inValue is in a list
not_inValue is not in a list
eqEqual (numeric for contextType: number)
neNot equal
gtGreater than
gteGreater than or equal
ltLess than
lteLess than or equal
containsSubstring match

Context Types

TypeBehavior
string (default)Plain string comparison
numberNumeric comparison (Double.parseDouble)
timeISO8601 date comparison
semverSemantic version comparison

Polling

The SDK uses HTTP polling to stay in sync. Default polling interval is 15 seconds (configurable via fetchTogglesInterval / refreshInterval).

The server supports ETag / If-None-Match conditional requests — if nothing changed, the server returns 304 Not Modified, saving bandwidth.

Caching Strategy

The SDK maintains an in-memory map of all flag rules. On each poll:

  • Full refresh on initial fetch
  • Conditional refresh via ETag on subsequent polls
  • Cache is replaced atomically — no partial updates
  • Cache is not persisted to disk — fresh rules on restart
ScenarioBehaviour
Rule update from serverEntire flag set replaced atomically
Network failureLast known rules continue to serve
Flag not foundisEnabled() returns false
Missing context attributeConstraint evaluates to false (rule doesn't match)

Client Initialisation

Java SDK

java
MozhnoConfig config = MozhnoConfig.builder()
    .appName("my-app")
    .instanceId("instance-1")
    .mozhnoUrl("http://localhost:8080")
    .apiKey("<api-key>")
    .fetchTogglesInterval(15)
    .sendMetricsInterval(60)
    .environment("production")
    .build();

MozhnoClient client = new DefaultMozhnoClient(config);
client.start();
boolean enabled = client.isEnabled("checkout_v2", context);

JavaScript / TypeScript SDK

typescript
import { MozhnoClient } from "@mozhno/client-js";

const client = new MozhnoClient({
  url: "https://mozhno.example.com",
  apiKey: "<api-key>",
  appName: "my-app",
  refreshInterval: 15,
  metricsInterval: 60,
  environment: "production",
});

await client.start();
const enabled = client.isEnabled("checkout_v2", { userId: "42" });

Configuration Options

OptionJS KeyJava KeyDefaultDescription
Server URLurlmozhnoUrlRequiredBase URL of your можно instance
API KeyapiKeyapiKeyRequiredAPI key for the environment
Application nameappNameappNameRequiredYour application identifier
Instance IDinstanceIdinstanceIdRequired (Java)Unique instance identifier
Poll interval (s)refreshIntervalfetchTogglesInterval15Polling interval in seconds
Metrics interval (s)metricsIntervalsendMetricsInterval60Metrics reporting interval
Environmentenvironmentenvironmentnull (Java) / "default" (JS)Environment name
Disable metricsdisableMetricsdisableMetricsfalseDisable metrics reporting

Evaluation Context

The context carries user/request attributes used for targeting:

Java:

java
MozhnoContext context = MozhnoContext.builder()
    .userId("12345")
    .sessionId("session-abc")
    .addProperty("country", "DE")
    .addProperty("plan", "enterprise")
    .build();

JavaScript:

typescript
const context = {
  userId: "12345",
  sessionId: "session-abc",
  country: "DE",
  plan: "enterprise",
};

Error Handling & Resilience

SDK Startup

ScenarioJava SDKJS SDK
Server reachable at startupFetches rules, client readyFetches rules, client ready
Server unreachable at startupThrows exception with synchronousFetchOnInitialisation(true). Otherwise starts and retries in backgroundPromise is rejected
Server goes down during runtimeUses cached state. Background retriesUses cached state. Background retries

Tip: In production, use synchronousFetchOnInitialisation(false) (default) — the SDK starts even if the server is temporarily down, and catches up when connectivity is restored.

Flag Evaluation

ScenarioBehavior
Flag not foundReturns false (fail-closed)
Flag exists, cache emptyReturns false — safe default
Context attribute missingRule referencing that attribute returns false
Network unavailableCached rules continue to work

Propagation Delay

Flag changes in the dashboard reach the SDK within one polling interval (default 15 seconds).

SDK Comparison

FeatureJava SDKJavaScript SDK
PlatformJVM 25+Node.js, Browser
Packagedev.mozhno:mozhno-client-java (Gradle)@mozhno/client-js (npm)
EvaluationSynchronousSynchronous (in-memory cache)
Thread safetyFully thread-safe (ConcurrentHashMap)Single-threaded event loop
Circuit breakerYes (5 failures → 60s cooldown)No
Spring BootAuto-configuration (mozhno.* properties)N/A

Performance Characteristics

MetricTypical Value
Initial fetch latency50-200 ms
Local evaluation time< 1 ms
Memory overhead~1 KB per flag
Polling payload (no changes)0 bytes (304 Not Modified)

Next Steps

  • Java SDK — Gradle setup, builder API, full reference.
  • JavaScript SDK — npm setup, async patterns.
  • REST API — Programmatic access to flags, segments, and environments.

Released under the AGPL v3.0 License.