Lab session
Feature Flags with OpenFeature and Unleash
Connect a service to an Unleash feature flag through OpenFeature and observe live behavior changes.
Overview¶
In this lab, you connect a running service to a boolean feature flag through OpenFeature and Unleash. You will observe how changing the flag updates application behavior without rebuilding or restarting the service.
🎯 Learning Goals¶
After completing this lab, you should be able to:
- Describe the different roles of OpenFeature, an OpenFeature provider, and Unleash
- Connect an application to an Unleash provider through OpenFeature
- Evaluate a boolean flag with a safe default
- Toggle a flag in Unleash and observe a running service change without restarting
- Explain why a flag update may take time to reach an application
Deliverables¶
By the end of the lab, the canary service in your fork should evaluate the supplied flag through OpenFeature and follow changes made in Unleash without restarting. You will submit the URL of the specific commit containing that integration through Canvas.
Setup¶
Fork the starter repository to your own account and open it in the provided devcontainer. Do not push commits to the upstream course repository. Work entirely in your fork. Run all commands in this lab from the repository root.
The devcontainer installs dependencies and starts the lab stack automatically. After it finishes, check the services:
docker compose ps
The postgres, unleash, stable, canary, and traefik services should be running and healthy.
The student-facing endpoints are the stable app on port 3000, the canary app on port 3001, the supplied route on port 8080, and Unleash on port 4242.
Unleash starts with a disabled boolean flag named lab06-new-flow in its development environment.
The canary loads UNLEASH_URL and UNLEASH_SDK_TOKEN from the local .env.lab file; do not copy them into source code.
Display the generated login for the local Unleash UI:
./scripts/show-credentials
Use ./scripts/start-lab to restart a stopped stack.
Use ./scripts/reset-lab to discard local service state, restore the disabled flag, and generate new credentials.
Run the checker before changing anything:
./scripts/check-lab
It should report that the flag integration is incomplete and stop before starting a clean stack. This initial failure confirms that you are starting from the expected state.
Tasks¶
Task 1: Observe the Starter Behavior¶
OpenFeature, the provider, and Unleash have different jobs
Unleash stores flag definitions and state and gives operators an interface for changing them. OpenFeature supplies the vendor-neutral API that application code uses to evaluate flags. The provider connects that API to Unleash. Register the provider once at startup, then use the OpenFeature client when handling requests.
Open the Unleash UI at http://localhost:4242 and find lab06-new-flow in the development environment.
Use the credentials printed by ./scripts/show-credentials to log in.
Confirm that it is disabled.
Call both versions directly:
curl --noproxy '*' --fail --silent http://localhost:3000/checkout
curl --noproxy '*' --fail --silent http://localhost:3001/checkout
Connectivity problems
If these commands fail or don't output anything, try substituting localhost by the output of ip route | awk '/^default/ {print $3; exit}'
Both responses initially report "new_flow":false.
The stable service always uses the old flow; the canary is prepared to evaluate the flag after you complete its integration.
Behavior activation and version exposure are separate controls
The supplied Traefik route on port 8080 distributes requests between the stable and canary versions. The feature flag controls behavior inside the canary after a request reaches it. You will operate the flag in this lab; the route is already configured.
Task 2: Connect the Canary to Unleash¶
The starter src/flag.js contains two incomplete functions and a helper that reads the local Unleash URL and SDK token.
Complete those functions so that the application:
- Registers an
UnleashProviderwith OpenFeature during startup and waits until the initial flag data is ready - Evaluates
lab06-new-flowthrough the OpenFeature client as a boolean with the safe defaultfalse
Use the installed provider's README under vendor/unleash-openfeature-node-provider/ and the OpenFeature SDK reference in Additional Resources to determine the required API calls.
Do not move provider construction into getNewFlow(); that function runs once for every canary request.
Restart the canary app after changing the code, then call its checkout endpoint directly:
docker compose restart canary
curl --noproxy '*' --fail --silent http://localhost:3001/checkout
The response should report the canary version with "new_flow":false.
Task 3: Change Behavior Without Restarting¶
Before changing the flag, predict whether enabling it will affect the stable service, the canary service, or both.
Enable lab06-new-flow in the Unleash UI.
Do not restart the app.
Wait a few seconds for the next provider refresh, then repeat the curl command until the response contains "new_flow":true.
Run the supplied route sampler while the flag is enabled:
./scripts/sample-routing 20
Requests that reach stable still report new_flow: false, while requests that reach canary report new_flow: true.
The exact version counts are not a deliverable.
A flag change is not visible immediately
The provider does not make a network request to Unleash for every evaluation.
It periodically refreshes a local snapshot, so a UI change may take a few seconds to appear.
The checker retries for a bounded time.
The false default is the value OpenFeature returns when it cannot produce a valid boolean evaluation; it is not a substitute for handling a provider startup failure.
Check your reasoning: Why did only the canary change?
Only the canary evaluates lab06-new-flow.
Changing the flag activates behavior inside that version; it does not change which version receives a request.
Disable the flag again before continuing.
Run the checker when the integration and experiment are complete:
./scripts/check-lab
The checker performs a focused OpenFeature integration test, starts a clean stack, and verifies the disabled–enabled–disabled transition against the same running canary. It does not grade the supplied route or require captured output from your experiment.
Additional Resources¶
- OpenFeature SDK for Node.js: provider registration, client setup, and boolean evaluation
- Unleash documentation: flag environments, SDK tokens, and activation state
- Unleash OpenFeature provider: provider configuration and startup
Submission¶
- Commit
src/flag.js, then push that commit to your fork. - Confirm that
git status --shortproduces no output, then run./scripts/check-labone last time. - Submit the URL of that exact commit—not a branch or pull request—using the Canvas link below.
This lab is graded pass/fail.