Summary
createCollection and getOrCreateCollection require users to write CreateCollectionOptions.builder()...build() for even simple cases like attaching an embedding function. This is the most common friction point in the API.
Current
Collection col = client.getOrCreateCollection(
"my-collection",
CreateCollectionOptions.builder()
.embeddingFunction(ef)
.build()
);
Proposed
Add Consumer<CreateCollectionOptions.Builder> overloads to Client:
// Consumer overload — library manages builder lifecycle
Collection col = client.getOrCreateCollection("my-collection", opts -> opts
.embeddingFunction(ef)
);
Methods to add
On the Client interface:
Collection createCollection(String name, Consumer<CreateCollectionOptions.Builder> options)
Collection getOrCreateCollection(String name, Consumer<CreateCollectionOptions.Builder> options)
On Collection interface (lower priority):
void modifyConfiguration(Consumer<UpdateCollectionConfiguration.Builder> config)
Implementation
Each overload delegates to the existing method:
default Collection createCollection(String name, Consumer<CreateCollectionOptions.Builder> configurer) {
CreateCollectionOptions.Builder builder = CreateCollectionOptions.builder();
configurer.accept(builder);
return createCollection(name, builder.build());
}
Design notes
- Additive only — existing
.builder().build() API stays for backwards compatibility
- Java 8 compatible —
Consumer<T> is in java.util.function since Java 8
- No overload explosion — only add Consumer variants for methods that take options objects (2-3 methods total)
- Record operation builders (
.add(), .query(), etc.) should NOT get Consumer overloads — their fluent + .execute() pattern is already optimal
What NOT to do
- Don't add Consumer overloads for
ChromaClient.builder() / .cloud() — called once at startup, explicit is fine
- Don't add overloads for Search/Knn/Rrf/GroupBy builders — already clean, low frequency
- Don't add convenience overloads like
getOrCreateCollection(name, ef) — keep API surface minimal per user preference
Precedent
This pattern is proven at scale by AWS SDK v2, Weaviate Java client v6, and Elasticsearch Java client.
References
Client interface: src/main/java/tech/amikos/chromadb/v2/Client.java
CreateCollectionOptions: src/main/java/tech/amikos/chromadb/v2/CreateCollectionOptions.java
UpdateCollectionConfiguration: src/main/java/tech/amikos/chromadb/v2/UpdateCollectionConfiguration.java
Summary
createCollectionandgetOrCreateCollectionrequire users to writeCreateCollectionOptions.builder()...build()for even simple cases like attaching an embedding function. This is the most common friction point in the API.Current
Proposed
Add
Consumer<CreateCollectionOptions.Builder>overloads toClient:Methods to add
On the
Clientinterface:Collection createCollection(String name, Consumer<CreateCollectionOptions.Builder> options)Collection getOrCreateCollection(String name, Consumer<CreateCollectionOptions.Builder> options)On
Collectioninterface (lower priority):void modifyConfiguration(Consumer<UpdateCollectionConfiguration.Builder> config)Implementation
Each overload delegates to the existing method:
Design notes
.builder().build()API stays for backwards compatibilityConsumer<T>is injava.util.functionsince Java 8.add(),.query(), etc.) should NOT get Consumer overloads — their fluent +.execute()pattern is already optimalWhat NOT to do
ChromaClient.builder()/.cloud()— called once at startup, explicit is finegetOrCreateCollection(name, ef)— keep API surface minimal per user preferencePrecedent
This pattern is proven at scale by AWS SDK v2, Weaviate Java client v6, and Elasticsearch Java client.
References
Clientinterface:src/main/java/tech/amikos/chromadb/v2/Client.javaCreateCollectionOptions:src/main/java/tech/amikos/chromadb/v2/CreateCollectionOptions.javaUpdateCollectionConfiguration:src/main/java/tech/amikos/chromadb/v2/UpdateCollectionConfiguration.java