Skip to content

Commit f51d020

Browse files
chore: update readme using template (#382)
* chore: update readme using template Signed-off-by: Todd Baert <[email protected]> * fixup: add complete API documentation Signed-off-by: Todd Baert <[email protected]> * Update README.md Co-authored-by: Justin Abrahms <[email protected]> Signed-off-by: Todd Baert <[email protected]> * Update README.md Co-authored-by: Justin Abrahms <[email protected]> Signed-off-by: Todd Baert <[email protected]> --------- Signed-off-by: Todd Baert <[email protected]> Co-authored-by: Justin Abrahms <[email protected]>
1 parent 22828d1 commit f51d020

File tree

2 files changed

+169
-76
lines changed

2 files changed

+169
-76
lines changed

CONTRIBUTING.md

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Welcome! Super happy to have you here.
1+
## Welcome! Super happy to have you here.
22

33
A few things.
44

@@ -10,10 +10,26 @@ We're not keen on vendor-specific stuff in this library, but if there are change
1010

1111
Any contributions you make are expected to be tested with unit tests. You can validate these work with `gradle test`, or the automation itself will run them for you when you make a PR.
1212

13-
Your code is supposed to work with Java 11+.
13+
Your code is supposed to work with Java 8+.
1414

1515
If you think we might be out of date with the spec, you can check that by invoking `python spec_finder.py` in the root of the repository. This will validate we have tests defined for all of the specification entries we know about.
1616

1717
If you're adding tests to cover something in the spec, use the `@Specification` annotation like you see throughout the test suites.
1818

19+
## Integration tests
20+
21+
The continuous integration runs a set of [gherkin integration tests](https://github.com/open-feature/test-harness/blob/main/features/evaluation.feature) using [`flagd`](https://github.com/open-feature/flagd). These tests do not run with the default maven profile. If you'd like to run them locally, you can start the flagd testbed with
22+
23+
```
24+
docker run -p 8013:8013 ghcr.io/open-feature/flagd-testbed:latest
25+
```
26+
and then run
27+
```
28+
mvn test -P integration-test
29+
```
30+
31+
## Releasing
32+
33+
See [releasing](./docs/release.md).
34+
1935
Thanks and looking forward to your issues and pull requests.

README.md

+151-74
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,43 @@
1-
# OpenFeature SDK for Java
1+
<!-- markdownlint-disable MD033 -->
2+
<p align="center">
3+
<picture>
4+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/open-feature/community/0e23508c163a6a1ac8c0ced3e4bd78faafe627c7/assets/logo/horizontal/white/openfeature-horizontal-white.svg">
5+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/open-feature/community/0e23508c163a6a1ac8c0ced3e4bd78faafe627c7/assets/logo/horizontal/black/openfeature-horizontal-black.svg">
6+
<img align="center" alt="OpenFeature Logo">
7+
</picture>
8+
</p>
29

10+
<h2 align="center">OpenFeature Java SDK</h2>
11+
12+
[![Specification](https://img.shields.io/static/v1?label=Specification&message=v0.5.2&color=yellow)](https://github.com/open-feature/spec/tree/v0.5.2)
313
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.openfeature/sdk/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.openfeature/sdk)
414
[![javadoc](https://javadoc.io/badge2/dev.openfeature/sdk/javadoc.svg)](https://javadoc.io/doc/dev.openfeature/sdk)
515
[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
6-
[![Specification](https://img.shields.io/static/v1?label=Specification&message=v0.5.2&color=yellow)](https://github.com/open-feature/spec/tree/v0.5.2)
716
[![Known Vulnerabilities](https://snyk.io/test/github/open-feature/java-sdk/badge.svg)](https://snyk.io/test/github/open-feature/java-sdk)
817
[![on-merge](https://github.com/open-feature/java-sdk/actions/workflows/merge.yml/badge.svg)](https://github.com/open-feature/java-sdk/actions/workflows/merge.yml)
918
[![codecov](https://codecov.io/gh/open-feature/java-sdk/branch/main/graph/badge.svg?token=XMS9L7PBY1)](https://codecov.io/gh/open-feature/java-sdk)
1019
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6241/badge)](https://bestpractices.coreinfrastructure.org/projects/6241)
1120

12-
This is the Java implementation of [OpenFeature](https://openfeature.dev), a vendor-agnostic abstraction library for evaluating feature flags.
13-
14-
We support multiple data types for flags (numbers, strings, booleans, objects) as well as hooks, which can alter the lifecycle of a flag evaluation.
21+
## 👋 Hey there! Thanks for checking out the OpenFeature Java SDK
1522

16-
This library is intended to be used in server-side contexts and has not been evaluated for use in mobile devices.
17-
18-
## Usage
19-
20-
While `Boolean` provides the simplest introduction, we offer a variety of flag types.
21-
22-
```java
23-
import dev.openfeature.sdk.Structure;
24-
25-
class MyClass {
26-
public UI booleanExample() {
27-
// Should we render the redesign? Or the default webpage?
28-
if (client.getBooleanValue("redesign_enabled", false)) {
29-
return render_redesign();
30-
}
31-
return render_normal();
32-
}
23+
### What is OpenFeature?
3324

34-
public Template stringExample() {
35-
// Get the template to load for the custom new homepage
36-
String template = client.getStringValue("homepage_template", "default-homepage.html");
37-
return render_template(template);
38-
}
25+
[OpenFeature][openfeature-website] is an open standard that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool.
3926

40-
public List<HomepageModule> numberExample() {
41-
// How many modules should we be fetching?
42-
Integer count = client.getIntegerValue("module-fetch-count", 4);
43-
return fetch_modules(count);
44-
}
27+
### Why standardize feature flags?
4528

46-
public HomepageModule structureExample() {
47-
Structure obj = client.getObjectValue("hero-module", previouslyDefinedDefaultStructure);
48-
return HomepageModule.builder()
49-
.title(obj.getValue("title"))
50-
.body(obj.getValue("description"))
51-
.build();
52-
}
53-
}
54-
```
29+
Standardizing feature flags unifies tools and vendors behind a common interface which avoids vendor lock-in at the code level. Additionally, it offers a framework for building extensions and integrations and allows providers to focus on their unique value proposition.
5530

56-
For complete documentation, visit: https://docs.openfeature.dev/docs/category/concepts
31+
## 🔍 Requirements:
5732

58-
## Requirements
5933
- Java 8+ (compiler target is 1.8)
6034

61-
## Installation
35+
Note that this library is intended to be used in server-side contexts and has not been evaluated for use in mobile devices.
6236

63-
### Add it to your build
37+
## 📦 Installation:
38+
39+
### Maven
6440

65-
#### Maven
6641
<!-- x-release-please-start-version -->
6742
```xml
6843
<dependency>
@@ -88,7 +63,7 @@ If you would like snapshot builds, this is the relevant repository information:
8863
</repositories>
8964
```
9065

91-
#### Gradle
66+
### Gradle
9267
<!-- x-release-please-start-version -->
9368
```groovy
9469
dependencies {
@@ -97,51 +72,153 @@ dependencies {
9772
```
9873
<!-- x-release-please-end-version -->
9974

100-
### Configure it
101-
To configure it, you'll need to add a provider to the global singleton `OpenFeatureAPI`. From there, you can generate a `Client` which is usable by your code. While you'll likely want a provider for your specific backend, we've provided a `NoOpProvider`, which simply returns the default passed in.
75+
### Software Bill of Materials (SBOM)
76+
77+
We publish SBOMs with all of our releases as of 0.3.0. You can find them in Maven Central alongside the artifacts.
78+
79+
## 🌟 Features:
80+
81+
- support for various backend [providers](https://docs.openfeature.dev/docs/reference/concepts/provider)
82+
- easy integration and extension via [hooks](https://docs.openfeature.dev/docs/reference/concepts/hooks)
83+
- bool, string, numeric and object flag types
84+
- [context-aware](https://docs.openfeature.dev/docs/reference/concepts/evaluation-context) evaluation
85+
86+
## 🚀 Usage:
87+
88+
### Basics:
89+
10290
```java
103-
class MyApp {
104-
public void example(){
105-
OpenFeatureAPI api = OpenFeatureAPI.getInstance();
106-
api.setProvider(new NoOpProvider());
107-
Client client = api.getClient();
108-
// Now use your `client` instance to evaluate some feature flags!
109-
}
91+
public void example(){
92+
93+
// configure a provider
94+
OpenFeatureAPI api = OpenFeatureAPI.getInstance();
95+
api.setProvider(new MyProviderOfChoice());
96+
97+
// create a client
98+
Client client = api.getClient();
99+
100+
// get a bool flag value
101+
boolean flagValue = client.getBooleanValue("boolFlag", false);
110102
}
111103
```
112-
## Contacting us
113-
We hold regular meetings which you can see [here](https://github.com/open-feature/community/#meetings-and-events).
114104

115-
We are also present on the `#openfeature` channel in the [CNCF slack](https://slack.cncf.io/).
105+
### Context-aware evaluation:
116106

117-
## Developing
107+
Sometimes the value of a flag must take into account some dynamic criteria about the application or user, such as the user location, IP, email address, or the location of the server.
108+
In OpenFeature, we refer to this as [`targeting`](https://docs.openfeature.dev/specification/glossary#targeting).
109+
If the flag system you're using supports targeting, you can provide the input data using the `EvaluationContext`.
118110

119-
### Integration tests
111+
```java
112+
// global context for static data
113+
OpenFeatureAPI api = OpenFeatureAPI.getInstance();
114+
Map<String, Value> attributes = new HashMap<>();
115+
attributes.put("appVersion", new Value(System.getEnv("APP_VERSION")));
116+
EvaluationContext apiCtx = new ImmutableContext(attributes);
117+
api.setEvaluationContext(apiCtx);
118+
119+
// request context
120+
Map<String, Value> attributes = new HashMap<>();
121+
attributes.put("email", new Value(session.getAttribute("email")));
122+
attributes.put("product", new Value(productId));
123+
String targetingKey = session.getId();
124+
EvaluationContext reqCtx = new ImmutableContext(targetingKey, attributes);
125+
126+
// use merged contextual data to determine a flag value
127+
boolean flagValue = client.getBooleanValue("some-flag", false, reqCtx);
128+
```
120129

121-
The continuous integration runs a set of [gherkin integration tests](https://github.com/open-feature/test-harness/blob/main/features/evaluation.feature) using [`flagd`](https://github.com/open-feature/flagd). These tests do not run with the default maven profile. If you'd like to run them locally, you can start the flagd testbed with
130+
### Providers:
122131

132+
To develop a provider, you need to create a new project and include the OpenFeature SDK as a dependency. This can be a new repository or included in [the existing contrib repository](https://github.com/open-feature/java-sdk-contrib) available under the OpenFeature organization. Finally, you’ll then need to write the provider itself. This can be accomplished by implementing the `FeatureProvider` interface exported by the OpenFeature SDK.
133+
134+
```java
135+
public class MyProvider implements FeatureProvider {
136+
@Override
137+
public Metadata getMetadata() {
138+
return () -> "My Provider";
139+
}
140+
141+
@Override
142+
public ProviderEvaluation<Boolean> getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) {
143+
// resolve a boolean flag value
144+
}
145+
146+
@Override
147+
public ProviderEvaluation<String> getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) {
148+
// resolve a string flag value
149+
}
150+
151+
@Override
152+
public ProviderEvaluation<Integer> getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) {
153+
// resolve an int flag value
154+
}
155+
156+
@Override
157+
public ProviderEvaluation<Double> getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) {
158+
// resolve a double flag value
159+
}
160+
161+
@Override
162+
public ProviderEvaluation<Value> getObjectEvaluation(String key, Value defaultValue, EvaluationContext ctx) {
163+
// resolve an object flag value
164+
}
165+
}
123166
```
124-
docker run -p 8013:8013 ghcr.io/open-feature/flagd-testbed:latest
125-
```
126-
and then run
127-
```
128-
mvn test -P integration-test
167+
168+
See [here](https://docs.openfeature.dev/docs/reference/technologies/server/java) for a catalog of available providers.
169+
170+
### Hooks:
171+
172+
Hooks are a mechanism that allow for the addition of arbitrary behavior at well-defined points of the flag evaluation life-cycle. Use cases include validation of the resolved flag value, modifying or adding data to the evaluation context, logging, telemetry, and tracking.
173+
174+
```java
175+
public class MyHook implements Hook {
176+
/**
177+
*
178+
* @param ctx Information about the particular flag evaluation
179+
* @param details Information about how the flag was resolved, including any resolved values.
180+
* @param hints An immutable mapping of data for users to communicate to the hooks.
181+
*/
182+
@Override
183+
public void after(HookContext ctx, FlagEvaluationDetails details, Map hints) {
184+
System.out.println("After evaluation!");
185+
}
186+
}
129187
```
130188

131-
## Releasing
189+
See [here](https://docs.openfeature.dev/docs/reference/technologies/server/java) for a catalog of available hooks.
132190

133-
See [releasing](./docs/release.md).
191+
### Logging:
134192

135-
### Software Bill of Materials (SBOM)
193+
The Java SDK uses SLF4J. See the [SLF4J manual](https://slf4j.org/manual.html) for complete documentation.
136194

137-
We publish SBOMs with all of our releases as of 0.3.0. You can find them in Maven Central alongside the artifacts.
195+
### Complete API documentation:
138196

139-
## Contributors
197+
See [here](https://www.javadoc.io/doc/dev.openfeature/sdk/latest/index.html) for the complete API documentation.
140198

141-
Thanks so much to our contributors.
199+
## ⭐️ Support the project
200+
201+
- Give this repo a ⭐️!
202+
- Follow us social media:
203+
- Twitter: [@openfeature](https://twitter.com/openfeature)
204+
- LinkedIn: [OpenFeature](https://www.linkedin.com/company/openfeature/)
205+
- Join us on [Slack](https://cloud-native.slack.com/archives/C0344AANLA1)
206+
- For more check out our [community page](https://docs.openfeature.dev/community/)
207+
208+
## 🤝 Contributing
209+
210+
Interested in contributing? Great, we'd love your help! To get started, take a look at the [CONTRIBUTING](CONTRIBUTING.md) guide.
211+
212+
### Thanks to everyone that has already contributed
142213

143214
<a href="https://github.com/open-feature/java-sdk/graphs/contributors">
144-
<img src="https://contrib.rocks/image?repo=open-feature/java-sdk" alt="Pictures of the folks who have contributed to the project"/>
215+
<img src="https://contrib.rocks/image?repo=open-feature/java-sdk" alt="Pictures of the folks who have contributed to the project" />
145216
</a>
146217

147218
Made with [contrib.rocks](https://contrib.rocks).
219+
220+
## 📜 License
221+
222+
[Apache License 2.0](LICENSE)
223+
224+
[openfeature-website]: https://openfeature.dev

0 commit comments

Comments
 (0)