Skip to content

Commit ae8fce8

Browse files
authored
feat: add a top-level method for accessing providers (#1152)
## This PR - add a top-level method for accessing providers ### Notes While working on some improvements to the way Suspense works in the React SDK, I ran into a few scenarios were having access to the provider itself was important. I needed a way to confidently tell that a provider was the noop provider since it has special properties like never being in a ready state. There are a few ways could could achieve this but I noticed that the Java SDK [already has methods](https://github.com/open-feature/java-sdk/blob/main/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java#L279) that expose the provider. It also allowed me to improve some of our existing tests. ### How to test Unit tests have been updated accordingly. Signed-off-by: Michael Beemer <[email protected]>
1 parent eec21dd commit ae8fce8

File tree

4 files changed

+57
-15
lines changed

4 files changed

+57
-15
lines changed

packages/server/src/open-feature.ts

+21
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,27 @@ export class OpenFeatureAPI
138138
return this;
139139
}
140140

141+
/**
142+
* Get the default provider.
143+
*
144+
* Note that it isn't recommended to interact with the provider directly, but rather through
145+
* an OpenFeature client.
146+
* @returns {Provider} Default Provider
147+
*/
148+
getProvider(): Provider;
149+
/**
150+
* Get the provider bound to the specified domain.
151+
*
152+
* Note that it isn't recommended to interact with the provider directly, but rather through
153+
* an OpenFeature client.
154+
* @param {string} domain An identifier which logically binds clients with providers
155+
* @returns {Provider} Domain-scoped provider
156+
*/
157+
getProvider(domain?: string): Provider;
158+
getProvider(domain?: string): Provider {
159+
return this.getProviderForClient(domain);
160+
}
161+
141162
setContext(context: EvaluationContext): this {
142163
this._context = context;
143164
return this;

packages/server/test/open-feature.spec.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ describe('OpenFeature', () => {
7474
it('should set the default provider if no domain is provided', () => {
7575
const provider = mockProvider();
7676
OpenFeature.setProvider(provider);
77-
const client = OpenFeature.getClient();
78-
expect(client.metadata.providerMetadata.name).toEqual(provider.metadata.name);
77+
const registeredProvider = OpenFeature.getProvider();
78+
expect(registeredProvider).toEqual(provider);
7979
});
8080

8181
it('should not change providers associated with a domain when setting a new default provider', () => {
@@ -85,11 +85,11 @@ describe('OpenFeature', () => {
8585
OpenFeature.setProvider(provider);
8686
OpenFeature.setProvider(domain, fakeProvider);
8787

88-
const defaultClient = OpenFeature.getClient();
89-
const domainSpecificClient = OpenFeature.getClient(domain);
88+
const defaultProvider = OpenFeature.getProvider();
89+
const domainSpecificProvider = OpenFeature.getProvider(domain);
9090

91-
expect(defaultClient.metadata.providerMetadata.name).toEqual(provider.metadata.name);
92-
expect(domainSpecificClient.metadata.providerMetadata.name).toEqual(fakeProvider.metadata.name);
91+
expect(defaultProvider).toEqual(provider);
92+
expect(domainSpecificProvider).toEqual(fakeProvider);
9393
});
9494

9595
it('should bind a new provider to existing clients in a matching domain', () => {

packages/web/src/open-feature.ts

+24-3
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,27 @@ export class OpenFeatureAPI
205205
return this;
206206
}
207207

208+
/**
209+
* Get the default provider.
210+
*
211+
* Note that it isn't recommended to interact with the provider directly, but rather through
212+
* an OpenFeature client.
213+
* @returns {Provider} Default Provider
214+
*/
215+
getProvider(): Provider;
216+
/**
217+
* Get the provider bound to the specified domain.
218+
*
219+
* Note that it isn't recommended to interact with the provider directly, but rather through
220+
* an OpenFeature client.
221+
* @param {string} domain An identifier which logically binds clients with providers
222+
* @returns {Provider} Domain-scoped provider
223+
*/
224+
getProvider(domain?: string): Provider;
225+
getProvider(domain?: string): Provider {
226+
return this.getProviderForClient(domain);
227+
}
228+
208229
/**
209230
* Sets the evaluation context globally.
210231
* This will be used by all providers that have not bound to a domain.
@@ -325,9 +346,9 @@ export class OpenFeatureAPI
325346
}
326347

327348
/**
328-
* A factory function for creating new named OpenFeature clients. Clients can contain
329-
* their own state (e.g. logger, hook, context). Multiple clients can be used
330-
* to segment feature flag configuration.
349+
* A factory function for creating new domain-scoped OpenFeature clients. Clients
350+
* can contain their own state (e.g. logger, hook, context). Multiple domains
351+
* can be used to segment feature flag configuration.
331352
*
332353
* If there is already a provider bound to this name via {@link this.setProvider setProvider}, this provider will be used.
333354
* Otherwise, the default provider is used until a provider is assigned to that name.

packages/web/test/open-feature.spec.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ describe('OpenFeature', () => {
7575
it('should set the default provider if no domain is provided', () => {
7676
const provider = mockProvider();
7777
OpenFeature.setProvider(provider);
78-
const client = OpenFeature.getClient();
79-
expect(client.metadata.providerMetadata.name).toEqual(provider.metadata.name);
78+
const registeredProvider = OpenFeature.getProvider();
79+
expect(registeredProvider).toEqual(provider);
8080
});
8181

8282
it('should not change providers associated with a domain when setting a new default provider', () => {
@@ -86,11 +86,11 @@ describe('OpenFeature', () => {
8686
OpenFeature.setProvider(provider);
8787
OpenFeature.setProvider(domain, fakeProvider);
8888

89-
const defaultClient = OpenFeature.getClient();
90-
const domainSpecificClient = OpenFeature.getClient(domain);
89+
const defaultProvider = OpenFeature.getProvider();
90+
const domainSpecificProvider = OpenFeature.getProvider(domain);
9191

92-
expect(defaultClient.metadata.providerMetadata.name).toEqual(provider.metadata.name);
93-
expect(domainSpecificClient.metadata.providerMetadata.name).toEqual(fakeProvider.metadata.name);
92+
expect(defaultProvider).toEqual(provider);
93+
expect(domainSpecificProvider).toEqual(fakeProvider);
9494
});
9595

9696
it('should bind a new provider to existing clients in a matching domain', () => {

0 commit comments

Comments
 (0)