# @theorchard/connector-splitio

Common logic for checking feature flags in GraphQL services using the Split.io SDK.

## Usage

### Basic usage

You first need to initialize the client. This will create a connection to Split.io, start polling the feature flags and keep them in memory. This should be done only once, when the server starts up.

```js
import { initSplitClient } from '@theorchard/connector-splitio';

const featuresConfig = {
    splitApiKey: 'SECRET',
    featuresInUse: ['feature_a', 'feature_b'], // This can be omitted, in that case every feature will be polled and kept in memory.
    debug: false, // Enables the Split.io SDK logging when true. Defaults to false.
};

initSplitClient(featuresConfig);
```

You can then check any feature flags passed in `featuresInUse`.

```js
import { isFeatureEnabled } from '@theorchard/connector-splitio';

// These values will typically come from the request headers and already be available in the Apollo `context` object.
const userContext = {
    identityId: '',
    profileType: '',
    profileId: '',
    legacyUserId: '',
    legacyAccountType: '',
    legacyAccountId: '',
};

if (isFeatureEnabled('feature_a', userContext)) {
    // Do something
} else {
    // Do something else
}
```

### Plugin usage

For Neo4j backed services using the `@requiresFeature` directive, where the feature flags need to be injected in the Apollo `context` object, you can use the provided plugin.

```js
import { env } from '@theorchard/graphql-server';
import { featuresPlugin } from '@theorchard/connector-splitio';

// Apollo Server Config
const createServerConfig = (baseConfig) => {
    const featuresConfig = {
        splitApiKey: 'SECRET',
        featuresInUse: ['feature_a', 'feature_b'], // This can be omitted, in that case every feature will be polled and kept in memory.
        debug: false, // Enables the Split.io SDK logging when true. Defaults to false.
        env: env.name, // Determines which environment to use when calling ows-users, `qa` or `prod`.
    };

    return {
        ...baseConfig,
        plugins: [...baseConfig.plugins, featuresPlugin(featuresConfig)],
    };
};
```

The resolved feature flags will be injected in the `cypherParams` under a key named `features`. You can then check a feature flag inside a cypher query.

```cypher
apoc.map.get($cypherParams.features, 'feature_a', false) = true
```

### Datasource usage

This package also exports a `FeaturesConnector` which can be used as an Apollo Datasource.

```js
import { FeaturesConnector } from '@theorchard/connector-splitio';

const featuresConfig = {
    splitApiKey: 'SECRET',
    featuresInUse: ['feature_a', 'feature_b'], // This can be omitted, in that case every feature will be polled and kept in memory.
    debug: false, // Enables the Split.io SDK logging when true. Defaults to false.
};

const featuresConnector = new FeaturesConnector(featuresConfig);
```

This class exposes two methods, `getFeatures` to get all the feature flags, and `hasFeature` to check if a feature flag is enabled.

```js
// These values will typically come from the request headers and already be available in the Apollo `context` object.
const userContext = {
    identityId: '',
    profileType: '',
    profileId: '',
    legacyUserId: '',
    legacyAccountType: '',
    legacyAccountId: '',
};

const features = featuresConnector.getFeatures(userContext);
// `features` will look like: [{ feature: 'feature_a', value: 'enabled' }, { feature: 'feature_b', value: 'control' }]

const featureAEnabled = featuresConnector.hasFeature('feature_a', userContext); // will return `true`
const featureBEnabled = featuresConnector.hasFeature('feature_b', userContext); // will return `false`
```
