growthbook / growthbook/growthbook-sdk-java
UserContextBuilder should accept a plain Map for attributes
- Dominant language
- Java
- Stars
- 17
- Forks
- 18
- Avg merge
- 16m
- Merged PRs (30d)
- 1
Description
### Summary
`UserContext.UserContextBuilder` currently only lets you provide attributes as either a
`com.google.gson.JsonObject` or a raw JSON `String` (`attributesJson`). Both are awkward
to use from application code, where attributes are almost always already available as a
plain `Map`.
### Current experience
```java
// Option A: build a JsonObject by hand
JsonObject attrs = new JsonObject();
attrs.addProperty("userId", userId);
attrs.addProperty("country", country);
UserContext ctx = UserContext.builder()
.attributes(attrs)
.build();
// Option B: hand-craft / serialize a JSON string
UserContext ctx = UserContext.builder()
.attributesJson("{\"userId\":\"" + userId + "\",\"country\":\"" + country + "\"}")
.build();
```
Both leak the Gson/JSON layer into calling code and are verbose and error-prone.
### Desired experience
```java
UserContext ctx = UserContext.builder()
.attributes(Map.of(
"userId", userId,
"country", country
))
.build();
```
### Proposed change
Add a `Map`-based overload to `UserContextBuilder` that converts the map into the internal
`JsonObject` using the SDK's shared Gson instance. It's a small, backwards-compatible
addition (the existing `JsonObject` and `attributesJson` overloads stay untouched).
```java
public UserContextBuilder attributes(Map attributes) {
this.attributes = attributes == null
? new JsonObject()
: GrowthBookJsonUtils.getInstance().gson
.toJsonTree(attributes).getAsJsonObject();
return this;
}
```
Note the `Map` wildcard so that `Map.of("userId", userId, "country", country)`
(inferred as `Map`) is accepted as well.
Checked on growthbook-sdk-java v0.10.10
Happy to see it in code if this looks good.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at UserContext.UserContextBuilder and inspect the existing attributes(JsonObject) and attributesJson overloads, then read GrowthBookJsonUtils to confirm how the shared Gson instance is exposed. Done means a Map can be passed as shown, null handling matches the request, and the existing overloads remain unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api
- Issue type
- Feature
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100