Java SDK

The official Torque Java SDK provides an HTTP client and TCP binary ingest client. Requires Java 21+ and uses the built-in java.net.http.HttpClient with Jackson 3 for JSON.

Installation

Add to your Maven pom.xml:

<dependency>
    <groupId>com.truespar</groupId>
    <artifactId>torque-http</artifactId>
    <version>0.5.0</version>
</dependency>

Or Gradle:

implementation 'com.truespar:torque-http:0.5.0'

HTTP Client

The TorqueHttpClient class provides full access to the Torque REST API:

import com.truespar.torque.http.*;

try (var client = new TorqueHttpClient("http://localhost:8108",
        new TorqueHttpClientOptions("YOUR_API_KEY"))) {

    // Health check
    var health = client.health();

    // Search
    var result = client.search("products", Map.of(
        "q", "running shoes",
        "query_by", "title,description"
    ));
    for (Hit hit : result.hits()) {
        System.out.println(hit.document().get("title"));
    }
}

Typed Search Parameters

SearchResult result = client.searchTyped("products",
    new SearchParameters()
        .q("laptop")
        .queryBy("title")
        .filterBy("price:>100")
        .sortBy("price:asc")
        .perPage(20));

for (Hit hit : result.hits()) {
    System.out.println(hit.document().get("title") + " - " + hit.document().get("price"));
}

Multi-Node with Failover

var options = new TorqueHttpClientOptions(
    "YOUR_API_KEY",
    List.of(
        new Node("https", "node1.example.com", 8108),
        new Node("https", "node2.example.com", 8108)
    ),
    3,                           // numRetries
    Duration.ofMillis(100),      // retryInterval
    Duration.ofSeconds(60),      // healthcheckInterval
    Duration.ofSeconds(30),      // timeout
    Duration.ofMinutes(5),       // transferTimeout
    false,                       // allowUntrustedCertificate
    false                        // sendApiKeyAsQueryParam
);
try (var client = new TorqueHttpClient(options)) {
    // ...
}

Collection Management

// Create a collection
client.createCollection(Map.of(
    "name", "products",
    "fields", List.of(
        Map.of("name", "title", "type", "string"),
        Map.of("name", "price", "type", "float", "sort", true),
        Map.of("name", "category", "type", "string", "facet", true)
    ),
    "default_sorting_field", "price"
));

// List collections
var collections = client.listCollections();

// Delete a collection
client.deleteCollection("products");

Document Operations

// Import documents (JSONL string)
String jsonl = """
    {"id": "1", "title": "Running Shoes", "price": 89.99}
    {"id": "2", "title": "Laptop Stand", "price": 49.99}
    """.strip();
var results = client.importDocuments("products", jsonl, "upsert");

// Export documents
String jsonl = client.exportDocuments("products", null);

// CRUD
client.createDocument("products", Map.of("id", "3", "title", "Mouse", "price", 29.99));
var doc = client.getDocument("products", "3");
client.updateDocument("products", "3", Map.of("price", 24.99));
client.deleteDocument("products", "3");

TCP Binary Ingestion

The TorqueIngestClient provides high-throughput document streaming via the binary TCP protocol:

import com.truespar.torque.http.*;

// Schema as list of field definitions (used for binary encoding)
var schema = List.of(
    Map.of("name", "title", "type", "string"),
    Map.of("name", "price", "type", "float"),
    Map.of("name", "category", "type", "string")
);

var ingest = new TorqueIngestClient();
ingest.connect("localhost", 8109);
try {
    ingest.startIngest("products");

    var batch = new ArrayList<Map<String, Object>>();
    for (int i = 0; i < 100000; i++) {
        batch.add(Map.of(
            "id", "product_" + i,
            "title", "Product " + i,
            "price", 9.99 + i * 0.01,
            "category", "Electronics"
        ));
        if (batch.size() == 5000) {
            ingest.sendBatch(batch, schema);
            batch.clear();
        }
    }
    if (!batch.isEmpty()) ingest.sendBatch(batch, schema);

    var ack = ingest.commit();
} finally {
    ingest.close();
}

TQBF Binary File Writer

var writer = new TorqueBinaryWriter(schema, Path.of("output.tqbf"));
for (int i = 0; i < 100000; i++) {
    writer.write(Map.of("id", "p_" + i, "title", "Product " + i, "price", 9.99));
}
writer.finalizeTqbf();
// Upload: POST /collections/products/documents/import-binary --data-binary @output.tqbf

Error Handling

The SDK uses typed exception classes for different error scenarios:

ExceptionHTTP Status
BadRequestException400
UnauthorizedException401
ForbiddenException403
ObjectNotFoundException404
ObjectAlreadyExistsException409
ServerErrorException500
ServiceUnavailableException503

All exceptions extend TorqueApiException which provides statusCode() and getMessage().