2.0.0 • Published 1 year ago

trepp-dpc v2.0.0

Weekly downloads
-
License
-
Repository
github
Last release
1 year ago

Overview

The trepp-dpc module currently implements a Feature Flag service enables both client and server side node applications to hot load configuration values dynamically via browser cookies.

The service automatically detects whether the integrated application is using the service directly in a web client or through web requests that are processed through server side NodeJS application. Depending on the context type (Server or Web Client) the feature flag service will utilize the correct underlying cookie store. document.cookie for dirext web client integrations and req.cookies/res.cookie for server side integrations.

By allowing QA/Engineers to dynamically cycle between old and new feature states via this hot-reloading mechanism, it enables for deployment-free and disruption-free testing of a live production application.

Usage

  1. npm install trepp-dpc library within the root of your application you wish to integrate with the Feature Flag Service

  2. Import the Feature Flag Service initialization functionality into your application in the file where you want to enable feature flag testing.

    // CommonJS 
    const { initFeatureFlags } = require('trepp-dpc')
    // ES6 Syntax 
    import { initFeatureFlags } from 'trepp-dpc'
  3. Initialize the feature flag service using the imported functionality from step 2. Once you initialize the service with a flagsConfig (can be env var stringified JSON object or just plain JSON object), the service will automatically load the config into the web client's cookies.

    The code below is just one simple example of initializing the service using a environment variable.

    const flagService = initFeatureFlags({ flagsConfig: process.env['FEATURE_FLAGS'] })

    After successfully initializing the flag service, you can then use the Public API methods detectFlag and toggleFlag to effectively enable and disable new features on the fly.

    Example detectFlag usage.

    if (detectFlag('new-feature-1')) {
     ...new feature logic here
    }
    
     Example toggleFlag usage. 
    
    // Remember this method can be directly invoked by the global window for easy testing
    toggleFlag('new-feature-1')

    Note* - If the integrating app is web facing, the toggleFlag method will be exposed to the clients browser window for easy toggling for QA/Engineers

Examples

Server-Side Node Example For this example I created a simple Node JS Express server using npm init -y. Then I installed all the dependencies listed within package.json.

{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"
  },
  "dependencies": {
    "cookie-parser": "^1.4.6",
    "cors": "^2.8.5",
    "dotenv": "^16.0.3",
    "express": "^4.17.1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Then I created a server.js file to use the feature flag service server side. I also created a public directory containing index.html containing script link to index.js

// server.js
const express = require('express');
const cors = require('cors');
const cookieParser = require('cookie-parser')
const app = express();
require('dotenv').config();
const { initFeatureFlags } = require('trepp-dpc');

app.use(cors({
    origin: 'http://localhost:5500',
    credentials: true,
}));

let service;

app.use(cookieParser())

app.get('/init-service', (req, res) => {
  // Example of init with object
  // service = initFeatureFlags({ flagsConfig: {
  //   'new-feature-1': false
  // } }, {req, res});
  service = initFeatureFlags({ flagsConfig: process.env['FEATURE_FLAGS'] }, {req, res});
  res.json({msg: 'Initialized Feature Flag Service and Set Feature-Flag Cookie succesfully'})
});

app.get('/detect/:flagName', (req, res) => {
  const { flagName } = req.params;
  res.json({[flagName]: service.detectFlag(flagName, req)});
});

app.get('/toggle/:flagName', (req, res) => {
  const { flagName } = req.params;
  service.toggleFlag(flagName, {req, res});
  res.json({msg: 'flag toggled'})
});

app.listen(3000, () => {
  console.log('Server listening on port 3000');
});

Here is an example of how you can overwrite the default cookie options:

  service = initFeatureFlags({ flagsConfig: process.env['FEATURE_FLAGS'], flagsCookieOpts: {
    maxAge: 0,
    path: "/",
    domain: "",
    secure: false,
    httpOnly: false,
    sameSite: "omit",
    date: new Date(),
    expires: "",
  } }, {req, res});

Next JS Web Client Example

For this example I created a Next JS Web Client using npx create-next-app@latest --typescript

Once I created the example project, I installed/linked the npm module for trepp-dpc and created a .env file at the root of my project with the following contents:

NEXT_PUBLIC_FEATURE_FLAGS={"new-feature-1": false, "new-feature-2": false}

Then I created simple logic to test integration of the the feature flag service. Here is the full integration of the service in the pages/index.tsx of the created Next JS project

import styles from '@/styles/Home.module.css'
import { useState, useEffect } from 'react';

// Import service init functionality 
import { initFeatureFlags } from 'trepp-dpc'

// Init service using process.env
const service = initFeatureFlags({ flagsConfig: process.env['NEXT_PUBLIC_FEATURE_FLAGS'] });

"use client"
export default function Home(): JSX.Element {

  const [domLoaded, setDomLoaded] = useState(false);

  useEffect(() => {
    setDomLoaded(true);
  }, []);

  return (
    <>
      <main className={styles.main}>
        {domLoaded && <div className='feature-flags-demo'>
          <h1>Feature Flag Simple Next JS Web Example</h1>
          <hr />
          <br />
          <br />
          <br />
          {/** Show old feature 1 */}
          {!service.detectFlag('new-feature-1') && <div className='feature-1'>
            <h2>
              This is Feature 1 - v1.0.0
            </h2>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Magni, doloremque natus. Rerum recusandae alias aperiam maxime deleniti perspiciatis officiis, Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur fuga quam delectus mollitia dolor praesentium impedit culpa ipsa asperiores nobis quos adipisci pariatur aliquid excepturi consequuntur illum, deserunt aperiam perspiciatis. minima nisi sunt illo vel fugiat totam at expedita qui? Vero!
          </div>}
          {/** Show new feature 1 */}
          {service.detectFlag('new-feature-1') && <div className='new-feature-1'>
            <h2>
              This is Feature 1 - v2.0.0
            </h2>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Magni, doloremque natus. Rerum recusandae alias aperiam maxime deleniti perspiciatis officiis, Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur fuga quam delectus mollitia dolor praesentium impedit culpa ipsa asperiores nobis quos adipisci pariatur aliquid excepturi consequuntur illum, deserunt aperiam perspiciatis. minima nisi sunt illo vel fugiat totam at expedita qui? Vero!
          </div>}
          <br />
          <hr />
          <br />
          {/** Show old feature 2 */}
          {!service.detectFlag('new-feature-2') && <div className='feature-2'>
            <h2>
              This is Feature 2 - v1.0.0
            </h2>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Magni, doloremque natus. Rerum recusandae alias aperiam maxime deleniti perspiciatis officiis, Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur fuga quam delectus mollitia dolor praesentium impedit culpa ipsa asperiores nobis quos adipisci pariatur aliquid excepturi consequuntur illum, deserunt aperiam perspiciatis. minima nisi sunt illo vel fugiat totam at expedita qui? Vero!
          </div>}
          {/** Show new feature 2 */}
          {service.detectFlag('new-feature-2') && <div className='new-feature-2'>
            <h2>
              This is Feature 2 - v2.0.0
            </h2>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Magni, doloremque natus. Rerum recusandae alias aperiam maxime deleniti perspiciatis officiis, Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur fuga quam delectus mollitia dolor praesentium impedit culpa ipsa asperiores nobis quos adipisci pariatur aliquid excepturi consequuntur illum, deserunt aperiam perspiciatis. minima nisi sunt illo vel fugiat totam at expedita qui? Vero!
          </div>}
        </div>
        }
      </main>
    </>
  )
}

Please view Full Documentation for more details.

2.0.0

1 year ago

1.0.0

1 year ago