Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Idea]: Decouple from LaunchDarkly (add more adapters) #40

Closed
tdeekens opened this issue Sep 16, 2017 · 8 comments
Closed

[Idea]: Decouple from LaunchDarkly (add more adapters) #40

tdeekens opened this issue Sep 16, 2017 · 8 comments
Assignees

Comments

@tdeekens
Copy link
Owner

Currently flopflip is coupled to "only" LaunchDarkly as a provider for toggles this can change.

The library could potentially allow multiple providers for toggles and was actually built from the ground up to do so. Another packages/* to integrate with another provider and the configuration on of a consumer facing package should then pick any of the integrations behind the scenes. The API for an integration has a quite minimal surface area:

  1. Initialize (with allowing to defer it)
  2. Flush flags
  3. Flush updates

An integration is in charge of "doing" the targeting etc.

A simple idea is to integrate with an autoupdating/polling/streaming localstorage integration. Any app could, when receiving flags from it's backend, flush these to localstorage where the adapter/integration picks them up and they're automatically flushed to redux or the broadcasting variant.

@tdeekens tdeekens self-assigned this Sep 16, 2017
@tdeekens
Copy link
Owner Author

tdeekens commented Oct 15, 2017

  1. This would probably involve renaming ld-wrapper to launchdarkly-adapter
  2. This would include adding a localstorage-adapter
  3. This would include having to pass in an adapter to ConfigureFlopFlip manually

Possible examples to configure adapters

import launchdarklyAdapter from '@flopflip/launchdarkly-adapter';

<ConfigureFlopFlip adapter={launchdarklyAdapter} adapterArgs={{ clientSideId: '123' }}>
  <App />
<ConfigureFlopFlip>

//..

import localstorageAdapter from '@flopflip/localstorage-adapter';

<ConfigureFlopFlip adapter={localstorageAdapter}>
  <App />
<ConfigureFlopFlip>

or something like

import launchdarklyAdapter from '@flopflip/launchdarkly-adapter';

launchdarklyAdapter.configure({ ldClientSideId: '123' })

<ConfigureFlopFlip adapter={launchdarklyAdapter}>
  <App />
<ConfigureFlopFlip>

All adapters would have to satisfy an API which could be roughly something like

  • onStatusStateChange: Used for adapter to be able to communicate if they're ready, setup up and able interact with their "backend"
  • onFlagsStateChange: Used to signal that the status of one or multiple flags has changed

@tdeekens
Copy link
Owner Author

The localstorage adapter would

  1. Define a "constant" as a key to where flags are status data is persisted
  2. Expose the API above (same for the launchdarkly-adapter`
  3. Poll localstorage and "emit" changes though the onFlagsStateChange callback

@tdeekens
Copy link
Owner Author

Another adapter could be an url-adapter which reads the flag statuses from the url. Behind the scenes it could use something like https://github.com/ReactTraining/history

@tdeekens
Copy link
Owner Author

Another dapter could be an api-adapter which behind the scenes fetches flags from some service.

apiAdapter.configure({ url: 'http://my-great-service.com/flags', userKey: '123' })

It would then poll for changes taking the url http://my-great-service.com/flags/123. It compares the newly polled flags to the last and triggers the onFlagsStateChange callback to flush them into redux or the broadcasting mechanism.

@tdeekens
Copy link
Owner Author

Curious to what @dferber90 thinks if he finds time having a look 😅 .

@dferber90
Copy link

dferber90 commented Oct 16, 2017

Adapters sound like a powerful concept.

Somehow seems like a perfect use-case for observable. But then again it would only raise more questions and we can achieve everything through functions already anyways. So I'd not use them.

After thinking about it a bit I'd prefer the version with adapterArgs as it provides a more natural to reconfigure the adapter in case information changes (like user logging out).

Maybe use a signature for the Adapter like this:

export default createAdapter = adapterArgs => (setStatusState, setFlagsState) => {
  setStatusState({ ready: true })
  setFlagsState({ FOO_FLAG: true })
}

Now either we only call the factory when adapterArgs' reference changes or we leave that to the adapter itself.

@tdeekens
Copy link
Owner Author

This will be part of #49. Thanks for all the feedback! Currently the launchdarkly-adapter has been ported while a memory-adapter has been created. The release will likely also contain a localstorage-adapter. Currently it feels like api-adapters are generally pretty bound to people's use cases, APIs and platforms. As a result I'd like to wait if someone actually needs on or if the implementation details settles.

@dferber90
Copy link

👍❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants