Skip to content

Conversation

@tylerjroach
Copy link

Builder Pattern and Jackson Extension for Mixpanel Java SDK

Overview

This PR introduces a flexible Builder pattern for MixpanelAPI configuration and adds an optional high-performance Jackson serialization extension as a separate module.

Key Changes

1. Builder Pattern Implementation

  • New MixpanelAPI.Builder class providing fluent API for configuration
  • Supports all existing constructor parameters:
    • Custom endpoints (events, people, groups, import)
    • Gzip compression toggle
    • Feature flags configuration (local/remote)
    • Custom JSON serializers
  • All existing constructors remain for backward compatibility

Example:

MixpanelAPI mixpanel = new MixpanelAPI.Builder()
    .useGzipCompression(true)
    .flagsConfig(localFlagsConfig)
    .jsonSerializer(new JacksonSerializer())
    .build();

2. JSON Serializer Abstraction

  • New JsonSerializer interface in com.mixpanel.mixpanelapi.internal package
  • OrgJsonSerializer - default implementation using org.json library (maintains backward compatibility)
  • Allows custom serialization implementations via builder
  • Allows use of optional Json plugin libraries without bloating the main mixpanel-java jar

3. Jackson Extension Module (mixpanel-java-extension-jackson)

  • Separate Maven artifact for optional high-performance serialization
  • JacksonSerializer implementation using Jackson streaming API
  • 2-5x performance improvement for large batches (50+ messages)
  • Only adds jackson-core dependency (lightweight)
  • Same package structure as main SDK for clean integration

Performance Benefits:

  • Optimal for /import endpoint (up to 2000 events)
  • Significant gains for high-volume event streams
  • Backward compatible - main SDK has no Jackson dependency

Usage:

<dependency>
    <groupId>com.mixpanel</groupId>
    <artifactId>mixpanel-java-extension-jackson</artifactId>
    <version>1.6.0</version>
</dependency>

4. Testing

  • Comprehensive tests for all 8 public constructors and builder patterns
  • JacksonSerializerTest uses JSONAssert to verify Jackson output matches OrgJson output exactly
  • Performance comparison tests for 2000-message batches
  • All tests validate both serializers produce identical JSON

5. Release Infrastructure

  • Updated GitHub Actions workflow to publish both artifacts to Maven Central
  • Both modules tested and verified in CI/CD pipeline
  • Release notes template includes both artifacts

6. Documentation Updates

  • Main README updated with builder pattern examples throughout
  • Extension module README with installation and usage instructions
  • All examples use builder pattern for consistency
  • Updated gzip compression, feature flags, and serialization sections

Breaking Changes

None. All existing constructors and APIs remain unchanged. This is a purely additive release.

Migration Guide

Users can optionally adopt the builder pattern:

Before:

MixpanelAPI mixpanel = new MixpanelAPI(true); // gzip compression

After:

MixpanelAPI mixpanel = new MixpanelAPI.Builder()
    .useGzipCompression(true)
    .build();

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a flexible Builder pattern for MixpanelAPI configuration and moves Jackson serialization support to a separate optional extension module. The changes maintain full backward compatibility while providing improved performance options for high-volume use cases.

Key Changes

  • Builder Pattern: New fluent API for MixpanelAPI configuration with support for all constructor parameters (custom endpoints, gzip compression, feature flags, custom serializers)
  • JSON Serializer Abstraction: Introduced JsonSerializer interface with OrgJsonSerializer as the default implementation, allowing custom serialization strategies
  • Jackson Extension Module: New mixpanel-java-extension-jackson artifact providing 2-5x performance improvement for large batches (50+ messages), eliminating automatic classpath detection in favor of explicit opt-in

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/main/java/com/mixpanel/mixpanelapi/MixpanelAPI.java Added Builder pattern and refactored constructors to use unified private constructor with JsonSerializer support
src/main/java/com/mixpanel/mixpanelapi/internal/JsonSerializer.java Removed getImplementationName() method to simplify interface
src/main/java/com/mixpanel/mixpanelapi/internal/OrgJsonSerializer.java Removed getImplementationName() implementation
src/main/java/com/mixpanel/mixpanelapi/internal/SerializerFactory.java Deleted automatic Jackson detection factory in favor of explicit configuration
src/test/java/com/mixpanel/mixpanelapi/internal/SerializerBenchmark.java Removed benchmark utility (not part of production code)
src/test/java/com/mixpanel/mixpanelapi/internal/JsonSerializerTest.java Updated tests to remove Jackson-specific tests and SerializerFactory tests
src/test/java/com/mixpanel/mixpanelapi/MixpanelAPITest.java Added comprehensive tests for Builder pattern and all 8 public constructors
pom.xml Removed optional Jackson dependency, updated version to 1.6.0
mixpanel-java-extension-jackson/pom.xml New extension module POM with jackson-core dependency
mixpanel-java-extension-jackson/src/main/java/com/mixpanel/mixpanelapi/internal/JacksonSerializer.java High-performance Jackson streaming API implementation
mixpanel-java-extension-jackson/src/test/java/com/mixpanel/mixpanelapi/internal/JacksonSerializerTest.java Tests verifying Jackson output matches OrgJson output exactly using JSONAssert
mixpanel-java-extension-jackson/README.md Documentation for Jackson extension module with installation and usage instructions
README.md Updated all examples to use Builder pattern, documented Jackson extension usage
.github/workflows/release.yml Enhanced to build, test, and deploy both main SDK and Jackson extension artifacts

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

String jacksonResult = jacksonSerializer.serializeArray(messages);
String orgResult = orgSerializer.serializeArray(messages);

jacksonResult = jacksonSerializer.serializeArray(messages);
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant serialization call. Line 36 already calls jacksonSerializer.serializeArray(messages) and stores the result in jacksonResult. Line 39 repeats the same call unnecessarily.

Remove line 39:

String jacksonResult = jacksonSerializer.serializeArray(messages);
String orgResult = orgSerializer.serializeArray(messages);

JSONArray array = new JSONArray(jacksonResult);
Suggested change
jacksonResult = jacksonSerializer.serializeArray(messages);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants