growthbook / growthbook/growthbook-sdk-java

UserContextBuilder should accept a plain Map for attributes

Open Beginner friendly
#232 3 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.