Skip to content

Commit

Permalink
Merge branch 'main' into exporter-metadata-android
Browse files Browse the repository at this point in the history
  • Loading branch information
thomaspoignant authored Jan 15, 2025
2 parents cd78ef4 + dfe49ed commit 384aa1d
Show file tree
Hide file tree
Showing 105 changed files with 7,012 additions and 21 deletions.
4 changes: 2 additions & 2 deletions cmd/relayproxy/helm-charts/relay-proxy/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ sources:
- "https://github.com/thomaspoignant/go-feature-flag"
description: A Helm chart to deploy go-feature-flag-relay proxy into Kubernetes
type: application
version: 1.40.0
appVersion: "v1.40.0"
version: 1.41.0
appVersion: "v1.41.0"
icon: https://raw.githubusercontent.com/thomaspoignant/go-feature-flag/main/logo.png
maintainers:
- name: thomaspoignant
Expand Down
2 changes: 1 addition & 1 deletion cmd/relayproxy/helm-charts/relay-proxy/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# relay-proxy

![Version: 1.40.0](https://img.shields.io/badge/Version-1.40.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.40.0](https://img.shields.io/badge/AppVersion-v1.40.0-informational?style=flat-square)
![Version: 1.41.0](https://img.shields.io/badge/Version-1.41.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.41.0](https://img.shields.io/badge/AppVersion-v1.41.0-informational?style=flat-square)

A Helm chart to deploy go-feature-flag-relay proxy into Kubernetes

Expand Down
8 changes: 4 additions & 4 deletions examples/openfeature_react/react-app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/openfeature_react/react-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"react-dom": "^19.0.0"
},
"devDependencies": {
"@types/react": "^19.0.2",
"@types/react": "^19.0.7",
"@types/react-dom": "^19.0.3",
"@typescript-eslint/eslint-plugin": "^8.20.0",
"@typescript-eslint/parser": "^8.19.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="7.0.0" />
<PackageReference Include="FluentAssertions" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="NUnit" Version="4.3.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
Expand Down
5 changes: 5 additions & 0 deletions website/versioned_docs/version-v1.41.0/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"position": 0,
"collapsible": true,
"collapsed": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"position": 30,
"collapsible": true,
"collapsed": true,
"label": "💡 Concepts",
"link": {
"title": "💡 Concepts"
}
}
55 changes: 55 additions & 0 deletions website/versioned_docs/version-v1.41.0/concepts/architecture.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
sidebar_position: 40
description: What is the GO Feature Flag architecture
---
# 🏗️ Architecture

## Overview
GO Feature Flag is a feature flagging system that allows you to manage feature flags in your application.
The architecture is really simple and efficient with the goal to be easy to use and let you experiment with feature flags in your application as fast as possible.

In most cases you have 1 microservice running the `relay-proxy` and multiple applications running the SDKs, nothing else.

:::note
GO Feature Flag can also be run without the `relay-proxy` if you only use the GO Module.

The relay-proxy is an API layer on top of the GO Module, so it has the same logic inside.
:::

## Architecture concepts

![GO Feature Flag architecture](/docs/openfeature/architecture.svg)

### 🧩 OpenFeature Providers
GO Feature Flag is working in collaboration with OpenFeature to be integrated with all the languages supported by GO Feature Flag.
To achieve this goal, we have created the OpenFeature providers that combines with OpenFeature SDKs to allow you to use GO Feature Flag in your application.

> **OpenFeature Providers**
> An SDK-compliant implementation which resolves flag values from a particular flag management system, allowing the use of the Evaluation API as an abstraction for the system in question.
This is what developers will use to interact with GO Feature Flag in their application.

### ↔️ Relay-Proxy
The relay-proxy is the only component you have to run in your infrastructure to use GO Feature Flag with the different SDKs.
This is a standalone GO binary that you can run in your infrastructure to expose the GO Feature Flag API to your applications.

:::info
Want to know more about the relay-proxy? [Check the relay-proxy documentation](../relay-proxy).
:::

The relay-proxy is designed to be simple, lightweight, and stateless. It operates without the need for any databases or complex systems, as it loads feature flag configuration files from a specified location and stores them in memory.

### ⬇️ Internal concepts
**You have 3 main concepts in GO Feature Flag architecture:**
- [retrievers](./retriever): This is the component in charge of fetching the feature flag configuration.
- [notifiers](./notifier): This is the component in charge of notifying external systems that a flag configuration has changed.
- [exporters](./exporter): This is the component in charge of exporting the flag evaluation results for analytics or monitoring.

Those 3 concepts are the core of GO Feature Flag and allows you to integrate GO Feature Flag in your current ecosystem with a minimum of effort.
Every component is designed to be as lightweight as possible and to be easy to configure.

## 🧑‍💻 Technologies

- GO Feature Flag is written in `golang`.
- The `retrievers`, `notifiers`, and `exporters` are using official libraries to interact with external systems.
- Providers are written in the language of the system they are interacting with and we are limiting the dependencies to the minimum to be as lightweight as possible.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
sidebar_position: 20
description: An evaluation context in a feature flagging system is crucial for determining the output of a feature flag evaluation. It's a collection of pertinent data about the conditions under which the evaluation is being made.
---
# 🔎 Evaluation Context

## Overview
All GO Feature Flag SDKs use an evaluation context to determine which variation of a feature flag to serve.

An evaluation context in a feature flagging system is crucial for determining the output of a feature flag evaluation.

It's a collection of pertinent data about the conditions under which the evaluation is being made.
his data can be supplied through a mix of static information _(server name, IP, etc ...)_ and dynamic inputs
_(information about the user performing the action, etc ...)_, along with state information that is implicitly carried
through the execution of the program.

## About contexts
GO Feature Flag evaluation contexts are data objects representing users, devices, organizations, and other entities that are used to determine which variation of a feature flag to serve.

The context is used to evaluate the [targeting queries](../configure_flag/target-with-flags.mdx) and determine which variation of a feature flag to serve to a user.

:::info
**Only the evaluation context attributes you provide are available for targeting queries.**

If you want to use a specific attribute in your targeting queries, you must include it in the evaluation context.
If not present the query will not apply.
:::

## Example context: Mike Wazowski at Monsters, Inc.

As an example, let's assume Mike Wazowski is one of your end users. He is a scare assistant who works on the scare floor at Monsters, Inc with James P. Sullivan.
Mike has two mobile devices, an Android phone and an iPad tablet. Mike uses your application on both devices as part of his work.

Given this information, you may know the following things about Mike Wazowski:

- his name, email and job title _("Scare assistant")_
- his employee ID _(used for the targetingKey)_
- his work station position _("scare floor")_
- his organization's name _("Monsters, Inc."),_
- his device's type _("iPad")_
- his coworker's name _("James P. Sullivan")_

Here is an example of what the data structure for Mike Wazowski evaluation context object might look like:

```json title="evaluation context"
{
"targetingKey": "34c7f8ab-6d14-4aa6-a77f-effc6245da6f",
"firstname": "Mike",
"lastname": "Wazowski",
"email": "mike.wazowski@monster.inc",
"organization": "Monsters, Inc.",
"jobFunction": "Scare assistant",
"location": "scare floor",
"coworker": "James P. Sullivan",
"device": "iPad"
}
```
## Targeting Key
:::info
**Targeting Key is a mandatory field in GO Feature Flag.**
:::

A **targeting key** is a unique identifier that represents the context of the evaluation _(email, session id, a fingerprint or anything that is consistent)_,
ensuring that they are consistently exposed to the same variation of a feature, even across multiple visits or sessions.

The targeting key is used to ensure that a user consistently receives the same variation of a feature flag over time.
For instance, **GO Feature Flag** ensures that in cases where a feature is being rolled out to a percentage of users, based on the targeting key, they will see the same variation each time they encounter the feature flag.

## Reserved properties in the evaluation context
When you create an evaluation context some fields are reserved for GO Feature Flag.
Those fields are used by GO Feature Flag directly, you can use them as will in your targeting queries but you should be aware that they are used internally for GO Feature Flag.

| Field | Description |
|---------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `gofeatureflag.currentDateTime` | If this property is set, we will use this date as base for all the rollout strategies which implies dates _(experimentation, progressive and scheduled)_.<br/>**Format:** Date following the RF3339 format. |
| `gofeatureflag.flagList` | If this property is set, in the bulk evaluation mode (for the client SDK) we will only evaluate the flags in this list.<br/>If empty or not set the default behavior is too evaluate all the flags.<br/>**Format:** []string |
63 changes: 63 additions & 0 deletions website/versioned_docs/version-v1.41.0/concepts/exporter.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
sidebar_position: 60
description: Exporter are used to export your evaluation data to a remote source.
---
import {integrations} from "@site/data/integrations";

# 🚚 Exporter

## Overview
In GO Feature Flag, an **exporter** is a component that sends flag evaluation results to external systems.
This allows you to track how your feature flags are being used, gather data for analysis, and monitor their impact on your application.

## About exporters
We have built the concept of **exporter** to allow you to export your evaluation data to a remote source, this can be useful in several occasion:
- **Analytics and Monitoring**: Exporters enable you to collect data on feature flag usage, such as how often a flag is evaluated, the percentage of users receiving a specific variation, and the context in which flags are evaluated. This data can be used for A/B testing, performance monitoring, and understanding user behavior.
- **Debugging and Troubleshooting**: By logging flag evaluations, exporters can help you identify issues related to feature flags, such as unexpected behavior or incorrect flag configurations.
- **Integration with External Systems**: Exporters facilitate integration with various monitoring, logging, and analytics platforms, allowing you to centralize your data and gain comprehensive insights.

## Synchronous vs Asynchronous exporters
Considering the volume of information to process and the potential impact on your application's performance, exporters can be synchronous or asynchronous depending on where the data is send.

<ul>
<li>
<span><strong>Synchronous exporters</strong>: These exporters send data immediately <i>(or near immediately)</i> after a flag evaluation. This is used for queue system or almost 0 latency write systems.</span>
<div className="flex gap-x-1 mt-1">
{
integrations.exporters.filter(exporter => exporter.type === 'sync').map((exporter) => (
<span className="inline-flex items-center rounded-md bg-gray-50 px-2 py-1 text-xs font-medium text-gray-600 ring-1 ring-inset ring-gray-500/10">{exporter.name}</span>
))}
</div>
</li>
<li className={"pt-5"}>
<span><strong>Asynchronous exporters</strong>: These exporters send data in batch, this is useful when you have a lot of data to send and you don't want to impact the performance of your application. This is used for all exporters writing files <i>(locally or remotely)</i>.</span>
<br /><span>Those exporters are using a buffer to store the data in memory before sending it. If for any reason the exporter can't send the data, the buffer will be used to store the data until the exporter can send it.</span>
<div className="flex gap-x-1 mt-1">
{
integrations.exporters.filter(exporter => exporter.type === 'async').map((exporter) => (
<span className="inline-flex items-center rounded-md bg-gray-50 px-2 py-1 text-xs font-medium text-gray-600 ring-1 ring-inset ring-gray-500/10">{exporter.name}</span>
))}
</div>
</li>
</ul>

## Supported exporters

<ul>
{integrations.exporters.map((exporter) => (
<li>{exporter.name}</li>
))}
</ul>

[Check how to configure the exporters](../integrations/export-evaluation-data)

## How Exporters Work

When a feature flag is evaluated using any of the SDK, GO Feature Flag notifies the configured exporters with the evaluation result. This result typically includes:

- The name of the flag.
- The variation returned.
- The targetingKey.
- The source of the evaluation (e.g., SERVER or PROVIDER).

The exporter then formats and sends this data to the configured destination.
91 changes: 91 additions & 0 deletions website/versioned_docs/version-v1.41.0/concepts/flag-evaluation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
sidebar_position: 10
description: Flag evaluation dynamically determines a feature flag's state at runtime based on context and targeting rules.
---
# 🚥 Flag Evaluation

## Overview
In a feature flag system, flag evaluation is the process of determining the current state _(which variant to use)_ of a feature flag for a given [evaluation context](./evaluation-context.md).

This process happens at runtime, allowing you to dynamically control the behavior of your application without redeploying code.

## What Happens During Evaluation?

The evaluation process typically involves these steps:

1. **Retrieving the Flag Configuration:** The system fetches the configuration for the specific flag being evaluated. This configuration includes information such as the flag's default value, targeting rules, and any other relevant settings.
2. **Contextual Input:** The evaluation receives context about the current request or user. This context can include information like:
- A targeting key
- Device type
- Location
- Custom attributes
3. **Rule Evaluation:** The system evaluates the targeting rules defined for the flag against the provided context. These rules determine which users or requests should see the feature enabled (or a specific variant). Common targeting strategies include:
- **Percentage rollout:** Enable the feature for a percentage of users _(e.g., 50%)_.
- **User targeting:** Enable the feature for specific users.
- **Attribute-based targeting:** Enable the feature based on user attributes _(e.g., users with a "premium" subscription)_.
4. **Returning the Flag Value:** Based on the rule evaluation, the system returns the appropriate value for the flag (e.g., `true`, `false`, or a variant value like `"variantA"`).

## Supported type of flags
GO Feature Flag supports a variety of flag types, including:
- **Boolean**
- **String**
- **Integer**
- **Double**
- **Object**

For each flag type, the SDKs are providing specific APIs to be able to retrieve your flag in the right type inside your code.

## Example

Let's say you have a feature flag called `new_checkout_flow` with the following configuration:

```yaml title="flags.goff.yaml"
new_checkout_flow:
variations:
enabled: true
disabled: false
targeting:
- query: user_segment eq "early_adopters"
variation: enabled
defaultRule:
percentage:
enabled: 20
disabled: 80
```
If a user belongs to the `early_adopters` segment, the flag evaluation will return `true`.
If a user does not belong to that segment, there's a **20% chance** the flag will return `true` due to the percentage rollout rule. Otherwise, the flag will return the `false`.

## Basic evaluation with GO Feature Flag

After setting up your flag configuration, you can evaluate the flag in your application code.
For this example *(in JS)*, we'll use the OpenFeature SDKs, with a GO Feature Flag provider:

```javascript
const evaluationContext = {
targetingKey: "<my-key>",
"user_segment": "early_adopters",
};
const defaultValue = false;
// get a boolean value
const boolValue = await client.getBooleanValue(
'new_checkout_flow',
defaultValue,
evaluationContext);
```

As you can see, the evaluation context API takes 3 parameters _(this is true in most languages)_:
- The name of the flag to evaluate.
- A default value to return if the flag is not found or the evaluation fails. The evaluation API will always return a value, even if there is an error.
- An evaluation context giving information about the current user or request _([more information about evaluation context](evaluation-context.md))_.

You can also see that we explicitely asking for a boolean value because `new_checkout_flow` is a boolean flag.

## Benefits of Dynamic Evaluation

Dynamic flag evaluation provides several advantages:
- **Instant control:** Change the state of features without deploying new code.
- **A/B testing:** Run experiments and gather data on different feature variations.
- **Gradual rollouts:** Release features to a small group of users before wider deployment.
- **Kill switches:** Quickly disable problematic features in production.
Loading

0 comments on commit 384aa1d

Please sign in to comment.