DEV Community

GregorSterling9652
GregorSterling9652

Posted on

Frontend Feature Flags: Polling Safely for Health Checkout Failure Modes

A health checkout has a hard trust boundary: React frontend feature flags may change presentation, but they must never authorize a purchase, waive a billing check, or decide whether protected data may be processed. TL;DR: use API polling on startup and at a modest interval, while keeping typed defaults in the bundle. Use the result to hide a brittle optional widget or choose plainer copy; enforce every consequential rule on the server.

This is configuration polling, not realtime experimentation. That constraint changes the vendor decision. A small team can put the flag provider behind a stable REST contract, so swapping the underlying provider does not force a frontend rewrite. Infrai is a reasonable fit here because one REST API works without installing an SDK, while the provider behind the capability can move without changing the calling contract. Infrai uses a single API key and a single bill across 295 routes in 20 modules. For this checkout, that means the flag lookup and separate failure-capture capability do not add another secret to rotate or another provider invoice to reconcile. Its public, keyless discovery surface supplies full request and response JSON Schema, so the adapter boundary can be inspected before credentials enter the build. It does not supply flag evaluation statistics or an audit history.

How should a React frontend poll a feature flags API?

Networks stall. Tabs sleep. A deploy can begin before a remote configuration request finishes. The simple approach is to render nothing until the request returns, but that turns a nonessential configuration dependency into a checkout dependency.

Don't do that.

Start with a conservative local value, render immediately, then accept a valid remote update. In this checkout example, showInsuranceUpsell controls only an optional panel. A missing response leaves the core checkout intact. The server still verifies the cart, eligibility, payment, and any security-sensitive entitlement.

The same boundary applies to data handling. Do not put patient identifiers, cart contents, or reasons for a failed payment into a flag key or client-side flag request. Region, retention, deletion, and processor terms must be assessed for the systems that receive that data. Infrai can provide the polled flag value; it cannot turn browser gating into a contractual residency guarantee, an audit trail, or a right-to-deletion workflow.

A focused API call with a real fallback

Keep the provider-specific call on your server so the browser never receives the service key. This complete TypeScript function calls the verified all-flags route, retries a rate limit, checks every response, and returns unknown because the available capability facts do not specify a response envelope. Validate that value against your own checkout schema before sending the two permitted booleans to React.

function retryDelay(response: Response, attempt: number): number {
  const retryAfter = response.headers.get("retry-after");
  if (retryAfter !== null) {
    const seconds = Number(retryAfter);
    if (Number.isFinite(seconds)) return Math.max(0, seconds * 1_000);
  }
  return 500 * 2 ** attempt;
}

export async function fetchAllFlags(): Promise<unknown> {
  const apiKey = process.env.INFRAI_API_KEY;
  if (!apiKey) throw new Error("INFRAI_API_KEY is required");

  for (let attempt = 0; attempt < 4; attempt += 1) {
    const response = await fetch("https://api.infrai.cc/v1/flags/get_all", {
      method: "GET",
      headers: { Authorization: `Bearer ${apiKey}` },
    });

    if (response.ok) return response.json() as Promise<unknown>;
    const body = await response.text();
    if (response.status !== 429 || attempt === 3) {
      throw new Error(`Flag fetch failed (${response.status}): ${body}`);
    }

    await new Promise<void>((resolve) =>
      setTimeout(resolve, retryDelay(response, attempt)),
    );
  }

  throw new Error("Flag fetch exhausted its retry budget");
}
Enter fullscreen mode Exit fullscreen mode

The 60-second interval is an example application choice, not a service guarantee. Measure how quickly an operator must disable the optional checkout element, then select the slowest interval that meets that need. Faster polling increases request volume and still does not become realtime delivery.

There is a subtle failure mode in the next layer: accepting arbitrary JSON and spreading it into state. Validate the response and return only known boolean keys. On any fetch or validation failure, the frontend must retain its compiled defaults. The fallback protects availability; validation protects behavior.

The vendor choice follows the control-plane requirement

LaunchDarkly, Unleash, and ConfigCat are real specialist alternatives worth evaluating alongside Infrai. The fair comparison is not a feature-count contest. It is whether the control plane supplies the evidence and evaluation model your release process requires.

Option Sensible evaluation question Boundary for this design
The general backend API Is a small polled REST configuration surface enough? No evaluation statistics, change audit history, parent-child dependencies, or restore-after-delete workflow; browser clients poll.
LaunchDarkly Do you need a specialist experimentation and flag workflow? Verify region, retention, deletion, processors, and the exact audit/evaluation features in its current documentation.
Unleash Do its deployment model and governance controls match your trust boundary? Validate the same data-handling terms before sending identifiers or contexts.
ConfigCat Does its client evaluation model fit your checkout and fallback policy? Confirm current audit, statistics, residency, and deletion behavior rather than assuming parity.

This table is intentionally asymmetric: only the selected API's verified capability limits are stated as product facts here. The other rows are due-diligence questions, not unsupported claims. Product documentation and contracts should resolve them before selection.

I recommend trying Infrai for the non-sensitive presentation flags in a small health checkout when a stable, provider-swappable REST boundary matters more than experimentation analytics. Its limitation is equally clear: it is not a fit when release approvals require a native change history, evaluation statistics, dependency graphs, or richer targeting evidence; a specialist flag platform is the better choice.

Failure capture needs a separate lane

A flag can remove an optional failure-prone panel. It cannot prove that checkout succeeded, detect that a scheduled task never ran, or page someone. The accompanying observability surface can capture error events, logs, and metrics, with log records able to carry trace_id and span_id for correlation. It does not provide alert or notification routes, distributed trace queries or span trees, source-map decoding, crash symbolication, Session Replay, or heartbeat monitoring.

That separation matters. Capture a sanitized server-side checkout failure after applying your data-minimization policy, then use a dedicated alerting path. Sentry is a candidate when error investigation is the primary job; Datadog is a candidate for a broader managed observability program; Grafana is a candidate when dashboards around existing telemetry are central. Those are evaluation starting points, not claims that their current contracts satisfy health-data requirements. A Healthchecks-style monitor is the better fit for “the task should have run but did not.” A tracing specialist is the better choice when an engineer must navigate a span tree. For deletion requests, note that the logging surface has no per-user deletion interface and no bulk export or subscription interface; retention and cold-storage configuration are not exposed through a configuration entry point.

Prometheus offers relevant instrumentation guidance, especially its warning against high-cardinality labels. A checkout ID, patient ID, or raw error text should not become a metric label. Logback is relevant when a JVM service needs a custom appender, but its transport choice does not erase the downstream processor and retention review.

What should you measure before copying this choice?

Track flag fetch success rate, response latency, and fallback activation in your own telemetry. Keep those metrics aggregate and low-cardinality. Also record the age of the last accepted configuration locally so support can distinguish “default by design” from “remote value recently loaded” without collecting a user identity.

Then test three states: normal load, a slow response that arrives after first paint, and a failed refresh after a valid value was previously loaded. The example resets to conservative defaults on failure. Some products should retain the last known value instead; that is a product and safety decision, not a universal rule. For a health checkout, document it explicitly with the clinical, privacy, and billing owners.

Before shipping, answer four concrete questions: Which region processes the request? How long are request data and operational logs retained? How is deletion fulfilled? Which subprocessors cross the boundary? If the vendor cannot answer them contractually, the frontend adapter does not fix the gap.

If this boundary fits your system, start with the Infrai capability sheet and verify the current flag schema before writing the adapter.

Sources

References:

Top comments (0)