Skip to content

Conversation

@imranismail
Copy link

@imranismail imranismail commented Jan 15, 2026

Adds forRootAsync() method to enable asynchronous configuration of the OpenFeature NestJS module using dependency injection. This allows OpenFeature to be configured with values from other providers (e.g., ConfigService) that are only available at runtime.

Changes

Implementation:

  • Migrated to NestJS ConfigurableModuleBuilder pattern for standardized async module support
  • Added forRootAsync() method that supports useFactory, useClass, and useExisting patterns
  • Refactored forRoot() to use the same internal buildModule() method for consistency
  • Changed provider initialization to use setProviderAndWait() instead of synchronous setProvider() for proper async handling
  • Moved OpenFeature SDK initialization into a factory provider to ensure it runs after module bootstrap

New Features:

  • forRootAsync() with full DI support (useFactory, inject, imports, etc.)
  • domains configuration in extras for domain-scoped client injection, unfortunately this is required to be able to build the client token for domains, since dependency tree needs to be determined synchronously at "build" time.
  • isGlobal configuration option (defaults to true)
  • Async provider initialization with proper dependency ordering

Migration Guide

Before (still works):

OpenFeatureModule.forRoot({
  defaultProvider: myProvider,
  useGlobalInterceptor: true,
})

After (with async config):

OpenFeatureModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (config: ConfigService) => ({
    defaultProvider: new Provider({
      apiKey: config.get<string>('PROVIDER_API_KEY'),
    }),
    providers: {
      'domain-scoped-client': new Provider({
        apiKey: config.get<string>('DOMAIN_A_API_KEY'),
      }),
    }
  }),
  inject: [ConfigService],
  isGlobal: true,
  useGlobalInterceptor: true,
  domains: ['domain-scoped-client'], // if using domain-scoped clients
})

Breaking Changes

Minor: The useGlobalInterceptor option moved from the main options to extras. However, this is backward compatible because the ConfigurableModuleBuilder merges extras into the options type.

@imranismail imranismail requested review from a team as code owners January 15, 2026 13:34
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @imranismail, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the OpenFeature NestJS module by introducing robust asynchronous configuration capabilities. It allows developers to dynamically configure OpenFeature providers and settings using NestJS's powerful dependency injection, making the module more flexible and adaptable to complex application setups where configuration values might not be immediately available at module registration time. The changes leverage NestJS's ConfigurableModuleBuilder for a more idiomatic and maintainable implementation.

Highlights

  • Asynchronous Module Configuration: Introduced a forRootAsync() method, enabling the OpenFeature NestJS module to be configured asynchronously using NestJS's dependency injection system. This supports useFactory, useClass, and useExisting patterns, allowing configuration values to be sourced from other providers available at runtime.
  • Standardized Module Building: Migrated the module implementation to use NestJS's ConfigurableModuleBuilder pattern, ensuring a standardized approach for module configuration and extensibility. The existing forRoot() method has been refactored to use a common buildModule() helper for consistency.
  • Asynchronous Provider Initialization: Changed OpenFeature provider initialization to use OpenFeature.setProviderAndWait() instead of synchronous setProvider(). This ensures proper asynchronous handling and correct ordering, as the OpenFeature SDK initialization is now moved into a factory provider that runs after module bootstrap.
  • New Configuration Options: Added domains configuration for injecting domain-scoped clients, and an isGlobal configuration option (defaulting to true) to control module globality. The useGlobalInterceptor option has been moved to extras but remains backward compatible.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@imranismail imranismail force-pushed the feat/nest-async-registration branch from 0be5fc6 to 7f20700 Compare January 15, 2026 13:37
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant and valuable feature by adding asynchronous module configuration capabilities to the OpenFeature NestJS module. The implementation correctly leverages NestJS's ConfigurableModuleBuilder and properly handles asynchronous provider initialization. My review includes a few suggestions to enhance maintainability and test quality, such as using a constant for a repeated injection token, renaming a parameter for better clarity, and improving the robustness of a test case for the logger functionality.

@lukas-reining
Copy link
Member

Hey @imranismail, thanks for the PR. This is a great addition.
I will try to review tomorrow!

@imranismail imranismail force-pushed the feat/nest-async-registration branch 3 times, most recently from 37cf4aa to 1e148fd Compare January 15, 2026 13:54
@imranismail imranismail force-pushed the feat/nest-async-registration branch from 1e148fd to ba4b0d6 Compare January 16, 2026 05:08
Signed-off-by: imranismail <hey@imranismail.dev>
@imranismail imranismail force-pushed the feat/nest-async-registration branch from ba4b0d6 to b657a92 Compare January 16, 2026 05:11
@imranismail
Copy link
Author

@lukas-reining I've changed the implementation slightly, also ensure existing test passes.

I'm a bit concerned about having to specify the domains again in the extras, happy to hear some ideas if you have.

@lukas-reining
Copy link
Member

Sorry for the delay @imranismail!
Will review tomorrow finally!

Signed-off-by: Imran Ismail <hey@imranismail.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants