Event Streaming updates
This relates to the primary purpose of the FeatureHub platform, which is a platform by which a client is able to connect and then receive a constant stream of real-time updates to the features as they change. This mechanism is enabled via Server Side Events (SSE).
REST-updates by usage/timeout
You can set a timeout period on the client, but it will only update if the features are evaluated. If a request is made for a feature and the timeout period has expired, the SDK will update the features in the background. This is ideal for situations where a user can be inactive for periods of time - e.g. Mobile or Web.
REST-updates by timer polling
You can set a polling time period on the client. At the end of the timeout a REST GET request will always be made, regardless of activity on the client. This is best for situations like Web where you want active updates. A user of your software would not sit on your website for a long time, and you want it to update fairly quickly.
Rollout strategies server and client evaluated
To apply rollout strategies (targeting and percentage rules) user context is required to be passed to the SDKs and can be evaluated either on the client or server. Percentage rollout requires use of the session
or userKey
attributes by default, however
using the Admin SDK you can configure alternative keys.
Fastly support
See Fastly details
Fastly CDN is supported for all available SDKs for streaming/SSE updates. Some SDKs, that only support SSE updates, do not support Fastly Polling. Please check in the capabilities table above.
Background Start
This relates to the ability for the application to connect to a FeatureHub Edge server in the background and complete the initial transactions and continue listening for updates - all in the background.
Block until Start
This is usually a capability provided instead of readiness listeners, whereby the library can be told to wait until the connection has been successfully established and there is a list of features, or the connection fails for some reason. It is used to ensure a client has a consistent set of features before functioning and is generally best used for server side software.
Readiness Listeners
These perform a similar function to Block until Start, but instead a server can call back or query the readiness status directly and perform the blocking function themselves. The ToDo Java and Typescript examples use this mechanism.
Feature Listeners
This allows client code to listen for changes in the state of a feature, and to trigger some action based on the new state. Generally the whole feature is passed to the listener for it to interrogate.
Feature Listener Removal
Some clients like to, or need to (usually UI related) remove listeners they have created. This allows them to do that.
Analytics Support
This is where the library has a mechanism to log an event, potentially attach metadata. The library captures the state of all the features at the point in time of the request and will pass it on to any registered Analytics provider. A platform can have analytics support but no analytics providers. We intend over time to support only one, where the data is posted to a backend service which you can then decide where to send and how to send the data.
Google Analytics
This is a client side implementation of the Analytics support.
You need to specify the User-ID
or CID
, your UA-
id and when logging an event, it will fire off into GA the event - one for each value of non-JSON features.
Catch & Release
Some clients don’t want the feature updates to be immediately triggered in real-time. These are usually those that use Feature Listeners and they want to hold onto the changes until they have informed the user there are changes - via some UI element (e.g. reload for new functionality). Catch and release mode normally includes a flag to set it, an extra callback to indicate new features have come in, and then a release method to indicate the new features should be released (their state changed and the listeners triggered). The Typescript, Javascript and Dart libraries all have examples of this.
If you use catch and release, it is worthwhile considering enabling OpenTracing feature overrides in production. You can configure feature interceptors to not be allowed to override locked features.
Client and server API Keys
FeatureHub supports two types of keys that can be used in the FeatureHub SDKs: Client Evaluated API Keys and Server Evaluated API Keys.
If you are using FeatureHub SaaS managed cloud service, SSE connection can only be made with client evaluated API keys and not supported with server evaluated API keys. |
The table below highlights the differences between the two key options.
Server evaluated key | Client evaluated key | |
---|---|---|
Use cases |
Browser apps, mobile apps |
Server apps |
Default feature values returned when requesting features |
Yes |
Yes |
Rollout strategies returned when requesting features |
No |
Yes |
Context change requires server request |
Yes |
No |
API Key should be treated as "secret" |
No* |
Yes |
(*) when a request is made to get features from FH server, it can, for example, be visible from the client’s browser Dev tools, including the request url, that consists of environment id and API Key. As Server evaluated key doesn’t return any sensitive information, it doesn’t need to be treated as "secret". On contrary, Client evaluated keys should be kept "secret" because they return the data that contains all the features and rollout strategy information which can be sensitive (e.g. user id’s, emails, etc.)
FeatureHub SDKs use a Context first API. This means you define information about who is using the features (including anonymous users), and the SDK will evaluate the feature values based on that information.
You can see what kind of data is being sent back for a given key by sending the request:
curl -v "http://YOUR-HOST/features/YOUR-API-KEY"
Client Evaluated API Keys
Client Side evaluation is intended for use in secure environments (such as microservices, e.g Node JS) and is intended for rapid client side evaluation, per request for example.
Client Evaluated Keys tell the Edge server to send you all of the data associated with the environment you are asking for. This means all features, their default values and their rollout strategies. This could potentially be sensitive information, and as such you should restrict what kinds of applications use Client Evaluated Keys.
Client Evaluated Keys are recommended for services - Microservices, Serverless methods, Monolith web apps, batch processes and so forth - where there is no user who can just grab the key, call the Edge API themselves and get the data.
The benefit of a client evaluated key is that you always have all the information you need to make a decision about the state of a feature. You can swap between different Contexts (which are usually in APIs a user’s request) as often as you like and always evaluate the features appropriate to that Context is already local.
This is what you want for when you are running something like a server application processing incoming requests, it is extremely scalable as everything is evaluated locally rather than needing to be sent to FeatureHub for checking.
For Client Evaluated Keys, going through the Context to get your features means all features are always evaluated as they pertain to the current context, locally.
Server Evaluated API Keys
Server Side evaluation is more suitable when you are using an insecure client. (e.g. Browser or Mobile). This also means you evaluate one user per client.
Server Evaluated Keys tell the Edge server to send you only the values of the features. If no Context is provided about a user, they will provide the _default value_of a feature (with one exception). If no information is provided, the rollout strategies generally don’t apply. For rollout strategies to apply, they have to be sent to the Edge server, and this is done either as a header or as a query parameter.
For this reason, each individual client (e.g. Browsers or Mobile devices) needs to send their Context information to the Edge server every time it changes. This usually means a slight delay each time the Context changes, it also means a lot of connections to your Edge servers, and it impacts their scaling.
With Server Evaluated Keys you have to balance how fast you want your clients to get updates (so do you use polling or near-realtime event-sourcing) versus how much you need in terms of resources.
For Server Evaluated Keys, going through the Context to get your features means if you change the Context, the request can hold on until the update has occured and then present you with an updated set of features.
Test automation support
Test client
Test Client / Feature Updater is designed to allow tests to change the values of features in their environments while they are running. The updates are made via PUT
to /features?apiKey=
.
This will require a service account with LOCK/UNLOCK and CHANGE_VALUE to allow tests to modify values. READ is implicit if CHANGE_VALUE is set.
Changes are checked against the latest version of the feature in the cache. Changes that match the current state are simply ignored (and a 200 response given). Changes generally take a second or two to propagate.
For other cases, the FeatureStateUpdate
class has three fields.
-
lock
- if passed it will change the state of the lock. You need LOCK permission to lock, UNLOCK permission to unlock. If a feature is locked, any attempt to change it will be ignored. -
value
- this is an "object" because it represents all types of values supported. It can be null. If it is null, and you want to ensure this is set to null (which is ignored for feature flags), make sure you setupdateValue
. -
updateValue
- this is specifically for the situation where you are setting a non feature flag to have a null value. Otherwise, passing a value will assume this is true.
There is also an alternative option to use Admin SDK API (ADK) to control feature values. Refer to Admin SDK API Keys and Admin SDK API docs |
Feature Interceptors
Feature Interceptors are the ability to intercept the request for a feature. They only operate in imperative state, so when code specifically requests the value of a feature, they don’t cause events to trigger. They are designed to function to enable specific kinds of use cases, such as:
-
allowing external storage of features, such as in a text file. This allows developers to override the value of features in their local running infrastructure without having to have a dedicated Environment for themselves or be connected.
-
allow per request overriding of features for example with OpenTracing or OpenTelemetry. Because of the nature of OpenTracing and OpenTelemetry, this allows you to listen to events from message queue systems like NATs, Kafka, ActiveMQ, etc.
It is unlikely you would be using these in production or staging environments as they are designed to make the development and testing of your feature based applications easier. They can however be used in production, and you can tell them that if the feature is locked, their statuses cannot be overridden. So in a test or development environment you should unlock your features and other environments you should lock them.
This prevents bad actors from poking at your apis and turning features on before they are ready.