Skip to main content

Server-Side SDKs

Ensure you have completed the Prerequisites section before continuing.

Installation & Configuration

Add the starter to your build.gradle:

build.gradle
dependencies {
implementation 'com.dashx:dashx-spring-boot-starter:1.4.1'
}

Or with Maven:

pom.xml
<dependency>
<groupId>com.dashx</groupId>
<artifactId>dashx-spring-boot-starter</artifactId>
<version>1.4.1</version>
</dependency>

Configure via application.properties:

src/main/resources/application.properties
dashx.public-key=${DASHX_PUBLIC_KEY}
dashx.private-key=${DASHX_PRIVATE_KEY}
dashx.target-environment=${DASHX_TARGET_ENVIRONMENT}

Or application.yml:

src/main/resources/application.yml
dashx:
public-key: ${DASHX_PUBLIC_KEY}
private-key: ${DASHX_PRIVATE_KEY}
target-environment: ${DASHX_TARGET_ENVIRONMENT}

The starter auto-configures a DashX bean — inject it wherever needed:

import com.dashx.DashX;
import org.springframework.stereotype.Service;

@Service
public class MyService {
private final DashX dashX;

public MyService(DashX dashX) {
this.dashX = dashX;
}
}

Optional properties

PropertyDefaultDescription
dashx.base-urlhttps://api.dashx.com/graphqlGraphQL endpoint
dashx.connection-timeout10000Connection timeout (ms)
dashx.response-timeout30000Response timeout (ms)
dashx.max-connections500Connection pool size
dashx.max-idle-time20000Max idle time per connection (ms)

Standalone (without Spring Boot)

Add the core SDK:

build.gradle
dependencies {
implementation 'com.dashx:dashx-java:1.4.1'
}

Configure manually:

import com.dashx.DashX;
import com.dashx.DashXConfig;

DashX dashX = DashX.getInstance();
dashX.configure(
new DashXConfig.Builder()
.publicKey("your-public-key")
.privateKey("your-private-key")
.targetEnvironment("production")
.build()
);

// When done, release resources
dashX.close();

Usage

note

All methods return CompletableFuture — the SDK uses non-blocking I/O under the hood (Spring WebFlux / Reactor Netty).

Identify a user

import java.util.Map;

dashX.identify(Map.of(
"uid", "123",
"email", "john@example.com",
"firstName", "John",
"lastName", "Doe"
)).thenAccept(account -> {
System.out.println("Identified: " + account.getUid());
});

Supported attributes: uid, anonymousUid, email, phone, name, firstName, lastName.

If no uid or anonymousUid is provided, the SDK generates an anonymous UID automatically.

Track events

// Basic event
dashX.track("Button Clicked");

// Event with a user
dashX.track("Button Clicked", "user-uid");

// Event with data
dashX.track("Button Clicked", Map.of(
"label", "Sign Up",
"placement", "header"
));

// Event with user and data
dashX.track("Button Clicked", "user-uid", Map.of(
"label", "Sign Up",
"placement", "header"
));

Send broadcasts

Send push notifications, emails, SMS, WhatsApp, in-app messages, and more:

import com.dashx.graphql.generated.types.CreateBroadcastInput;
import com.dashx.graphql.generated.types.TemplateSubkind;

// Using a template
dashX.sendBroadcast(
CreateBroadcastInput.newBuilder()
.templateSubkind(TemplateSubkind.PUSH)
.templateIdentifier("welcome-push")
.content(Map.of("to", List.of("user-123", "user-456")))
.data(Map.of("promo_code", "WELCOME10"))
.build()
);

// Using inline content
dashX.sendBroadcast(
CreateBroadcastInput.newBuilder()
.templateSubkind(TemplateSubkind.PUSH)
.content(Map.of(
"to", List.of("user-123"),
"title", "Order shipped!",
"body", "Your order #1234 is on its way."
))
.build()
);

Supported TemplateSubkind values: EMAIL, SMS, PUSH, WHATSAPP, IN_APP.

Search records (CMS)

import com.dashx.graphql.utils.SearchRecordsOptions;

dashX.searchRecords("blog",
SearchRecordsOptions.newBuilder()
.filter(Map.of("status", "published"))
.order(List.of(Map.of("created_at", "DESC")))
.limit(10)
.page(1)
.language("en_US")
.preview(true)
.build()
).thenAccept(records -> {
records.forEach(System.out::println);
});

Asset management

// Get a single asset
dashX.getAsset("asset-id").thenAccept(asset -> {
System.out.println(asset.getUrl());
});

// List assets with filtering and pagination
dashX.listAssets(
Map.of("resourceId", "resource-uuid"), // filter
List.of(Map.of("createdAt", "DESC")), // order
10, // limit
1 // page
);

Issue management

import com.dashx.graphql.generated.types.CreateIssueInput;
import com.dashx.graphql.generated.types.UpsertIssueInput;
import com.dashx.graphql.generated.types.IssuePriority;

// Create an issue
dashX.createIssue(
CreateIssueInput.newBuilder()
.title("Login button broken on mobile")
.issueType("Bug")
.issueStatus("Open")
.group("Engineering")
.priority(IssuePriority.HIGH)
.description("The login button is unresponsive on iOS Safari.")
.labels(List.of("mobile", "auth"))
.properties(Map.of("browser", "Safari", "os", "iOS 17"))
.requestedBy(Map.of("uid", "user-123", "name", "Jane Doe"))
.build()
);

// Upsert with idempotency key
dashX.upsertIssue(
UpsertIssueInput.newBuilder()
.title("Bug report")
.issueType("bug")
.idempotencyKey("unique-key-123")
.build()
);

Error handling

The SDK throws three types of exceptions, all extending DashXException (a RuntimeException):

  • DashXConfigurationException — Missing or invalid configuration (e.g., null publicKey, negative timeout)
  • DashXValidationException — Invalid method arguments (e.g., null options, empty event name)
  • DashXGraphQLException — Errors returned by the DashX API; call getErrors() to inspect individual GraphQL errors
import com.dashx.exception.*;

dashX.track("Event").exceptionally(ex -> {
Throwable cause = ex.getCause();
if (cause instanceof DashXGraphQLException graphQLEx) {
// Server returned GraphQL errors
graphQLEx.getErrors().forEach(e -> System.err.println(e.getMessage()));
} else if (cause instanceof DashXValidationException) {
// Invalid arguments (null event name, etc.)
} else if (cause instanceof DashXConfigurationException) {
// SDK not configured or misconfigured
}
return null;
});

Resource cleanup

Call close() to release the underlying connection pool when the SDK is no longer needed. In Spring Boot, this is handled automatically.

DashX dashX = DashX.getInstance();
dashX.configure(config);

// ... use the client ...

dashX.close();

Named instances

For advanced use cases (e.g., different keys for analytics vs. notifications):

DashX analytics = DashX.getInstance("analytics");
analytics.configure(analyticsConfig);

DashX notifications = DashX.getInstance("notifications");
notifications.configure(notificationsConfig);

// Clean up a specific instance
DashX.removeInstance("analytics");

// Or clean up all instances
DashX.resetInstances();

Connection tuning

The SDK uses connection pooling with configurable timeouts. Here are recommended values by traffic level:

Scenarioconnection-timeoutresponse-timeoutmax-connectionsmax-idle-time
Low (< 100 req/min)100003000010020000
Medium (100–1000 req/min)100003000050030000
High (> 1000 req/min)1500045000100060000
Behind proxy / load balancer200006000050045000

Troubleshooting

If you encounter "Connection prematurely closed BEFORE response" errors, increase timeouts:

dashx.response-timeout=60000
dashx.connection-timeout=20000

Enable debug logging in application.properties:

logging.level.com.dashx=DEBUG
logging.level.reactor.netty=DEBUG