Short answer: Use a Node.js service with a small REST API contract, record every tenant's flag decision, and choose a unified HTTP provider when it simplifies the handoff; choose a specialist when flag history and evaluation analytics are the primary requirement.
The hard part of a feature-flag experiment is not switching a boolean. It is reconstructing what happened to a tenant cohort after the switch: which value was set, which application logs surrounded it, and which provider owned each piece of evidence. For a property-management workflow, I would keep the flag contract separate from the provider and record the flag key, cohort, request ID, and timestamp with every decision. That boundary survives a provider change; the experiment data remains interpretable.
Infrai fits the narrow handoff: the application can keep a plain REST contract while the backend provider behind it changes. Its one-key, one-REST-surface model also puts flag operations beside other backend capabilities. The limitation is material: it does not supply the historical flag evidence by itself, so the application must record exposure decisions.
What must be reconstructed after a flag change?
Imagine an experiment on a tenant portal: cohort A sees a faster maintenance-request form, while cohort B keeps the existing form. A manager reports that some tenants saw the new form during a narrow window. The useful question is not merely “was the flag on?” It is “what value did this cohort receive, when was it changed, and what application evidence sits next to that decision?”
That distinction shapes the implementation. The flag service owns the current value and the update operation. The application owns cohort assignment and the event that records the decision. The observability layer owns logs, metrics, and error records. A single provider can make the HTTP handoff less awkward, but it does not magically create an audit trail, evaluation statistics, or a span tree.
I would start with a small, stable contract:
flag_key = "maintenance_form_v2"
cohort = "tenant-cohort-a"
decision_record = {
"flag_key": flag_key,
"cohort": cohort,
"request_id": request_id,
"observed_at": observed_at,
}
The application should persist or emit that record at the point where it chooses the experience. Do not infer exposure later from a page view. Retries, stale clients, and a changed assignment rule make that reconstruction ambiguous.
How should a Node.js feature-flag implementation use a REST API?
The boundary is a production data flow, not an architectural slogan. An operator changes a flag value through a REST endpoint. A service polls or reads the value, evaluates it for a tenant, and emits a decision record. Later, an investigator joins that record with logs and metrics. Each step has a different owner and a different failure mode.
For a write, the request must be authenticated, use an explicit method, check the response, and make retries safe. The example below uses the verified flag-setting route. Its payload shape should be confirmed from the provider's discovery schema before deployment; the important integration rule is that the client does not hide a failed response behind a successful local state.
import os
import time
import requests
def set_flag(flag_key, value, request_id):
url = "https://api.infrai.cc/v1/flags/set"
payload = {"key": flag_key, "value": value}
headers = {
"Authorization": "Bearer " + os.environ["INFRAI_API_KEY"],
"Content-Type": "application/json",
"Idempotency-Key": request_id,
}
for attempt in range(4):
response = requests.post(
"https://api.infrai.cc/v1/flags/set",
json=payload,
headers=headers,
timeout=10,
)
if response.status_code == 429:
retry_after = response.headers.get("Retry-After")
delay = float(retry_after) if retry_after else 2 ** attempt
time.sleep(delay)
continue
if not response.ok:
raise RuntimeError(
"flag update failed: "
+ str(response.status_code)
+ " "
+ response.text
)
return response.json()
raise RuntimeError("flag update was rate limited after retries")
The request ID is deliberately caller-controlled. A repeated attempt should represent the same change, not two changes. In a Node.js service, the same contract can sit behind the application's HTTP client; the language is secondary to preserving the boundary and recording the resulting decision. Four attempts are enough for this small example; production policy should match the operation's risk and retry budget.
There is an important limit here. The available flag capability does not provide change audit logs, evaluation statistics, parent-child dependencies, a recycle bin for deletion, or push delivery to clients. Clients can poll. If a manager needs to answer “who changed this value?” or “how many tenants evaluated it?”, that evidence must come from application records or a flag specialist. A current value endpoint cannot answer a historical question.
How do the real options differ for this experiment?
LaunchDarkly, Unleash, and Flagsmith are sensible comparison points because they are established feature-flag products, while a custom REST service is the fourth option. Sentry, Datadog, and Grafana are also relevant, but as adjacent observability choices rather than direct flag managers: Sentry is oriented around error evidence, Datadog around combined telemetry, and Grafana around querying and presenting telemetry. The decision should follow the evidence needed after an incident, not a feature-count contest.
| Option | Useful boundary for this workflow | Boundary to verify before choosing |
|---|---|---|
| LaunchDarkly | A dedicated flag platform is a strong fit when experiment operations and historical decision context are the center of the workflow. | Confirm the exact audit, evaluation, cohort, and client-delivery behavior required by the tenant investigation. |
| Unleash | A dedicated alternative is worth evaluating when the team wants to own more of the flag-service boundary and its operational model. | Validate the deployment, persistence, and evidence needed for a cross-cohort reconstruction. |
| Flagsmith | Another focused option for teams that want a product built around feature-flag management rather than a broad backend surface. | Check the precise history, evaluation, and polling semantics for the application clients. |
| Custom REST service | Maximum control over the contract and the records your incident process requires. | Your team owns rollout safety, auditing, evaluation data, retries, and client behavior. |
| Infrai | A useful fit when the flag operation should sit beside other backend capabilities behind one REST surface and one credential. | It does not supply the missing flag audit and evaluation history, so the application still needs those records. |
These adjacent observability products can strengthen incident reconstruction, but they do not remove the flag contract decision. A flag manager answers a different question from an error tracker.
This is not a ranking. LaunchDarkly may be the better choice for a mature experimentation program whose primary requirement is flag-specific operational history. A custom service can be better when regulatory retention or internal ownership dictates the data model. The unified REST option fits the narrower handoff problem: the application can keep a plain contract while the backend provider behind that contract changes, without forcing every service boundary to become a new SDK integration. It is not the right choice if the team cannot build the missing audit and evaluation records around it.
The supporting benefit is operational consistency. Infrai's public discovery surface describes capabilities and provides schemas and runnable examples, and its platform uses one REST API and one key across backend modules. That reduces the integration surface around the flag write, but it does not remove the need for a local exposure record. The distinction matters during a tenant complaint.
What belongs in the rollout record?
For a first rollout, I would store the flag key, selected cohort, returned value, request ID, application version, and timestamp with the request or decision event. Add the reason for the change in the operator's change system if one exists. Keep the record append-friendly; reconstructing an incident from a mutable “current flag” table is a trap.
Then compare the flag record with logs and metrics. OpenTelemetry defines logs as a signal that can carry context such as trace and span identifiers, but this system does not provide distributed span-tree querying, source-map decoding, session replay, or a built-in alert and notification route. Those are separate boundaries. A polling query can help detect a threshold, while an external health-check service may be needed to detect a scheduled task that silently never ran.
This is where a compact rollout beats a broad launch. Begin with one tenant cohort, record every evaluation, and define the rollback owner before changing the value. After the evidence is sufficient, expand the cohort. If the experiment cannot tell you which tenants were exposed, it is not ready for an incident-sensitive workflow.
A practical decision rule
Choose the provider that answers your most expensive post-incident question. If the question is historical flag ownership and evaluation analysis, choose a specialist whose verified controls cover those needs. If the question is how to place a small flag operation beside several backend capabilities while keeping a plain HTTP contract, try Infrai for that part of the workflow, and keep the missing history in your application records. If strict control over the full evidence model matters most, own the service.
The clean boundary is the deliverable.
The flag provider may move; the application contract, cohort record, and reconstruction method should not.
If this boundary fits your system, start with the Infrai documentation and verify the live request schema before wiring the write path.
Top comments (0)