Migrating from classic client
This guide helps you migrate an existing application from the Classic Aerospike client to the Developer SDK.
Why migrate?
The Developer SDK offers several advantages over the classic client:
- Cleaner syntax — Chainable, fluent APIs reduce boilerplate
- AEL queries — Human-readable filter expressions
- Better error handling — Actionable errors with recovery suggestions
- Decoupled configuration — Separate connection from behavior
Before you start
- Ensure your Aerospike server is compatible (version 6.0+)
- The Developer SDK is a separate package — it doesn’t replace the classic client
- You can run both clients side-by-side during migration
Conceptual changes
Connection model
Classic: Direct client with embedded configuration
SDK: Separate Cluster (connection) and Session (behavior)
// Classic: Everything in one placeAerospikeClient client = new AerospikeClient( new ClientPolicy(), new Host("localhost", 3000));import com.aerospike.client.sdk.policy.Behavior;import com.aerospike.client.sdk.Cluster;import com.aerospike.client.sdk.ClusterDefinition;import com.aerospike.client.sdk.Session;
// SDK: Connection separate from behaviortry (Cluster cluster = new ClusterDefinition("localhost", 3000).connect()) { Session session = cluster.createSession(Behavior.DEFAULT);}# Classic: Everything in one placeclient = aerospike.client({ 'hosts': [('localhost', 3000)]}).connect()from aerospike_sdk import Behavior, ClusterDefinition
# SDK: Connection separate from behaviorasync with await ClusterDefinition("localhost", 3000).connect() as cluster: session = cluster.create_session(Behavior.DEFAULT)Key and record references
Classic: Explicit Key objects with namespace, set, and user key
SDK: DataSet represents namespace + set, .id() creates record references
Key key = new Key("test", "users", "user-1");DataSet users = DataSet.of("test", "users");RecordRef ref = users.id("user-1");key = ("test", "users", "user-1")users = DataSet.of("test", "users")ref = users.id("user-1")Operation mapping
Create (put)
client.put(null, key, new Bin("name", "Alice"), new Bin("age", 30));session.insert(users) .bins("name", "age") .id("user-1").values("Alice", 30) .execute();client.put(key, {"name": "Alice", "age": 30})await session.insert(key=users.id("user-1")).put( {"name": "Alice", "age": 30}).execute()Read (get)
Record record = client.get(null, key);String name = record.getString("name");import com.aerospike.client.sdk.Record;import com.aerospike.client.sdk.RecordStream;
String name;try (RecordStream stream = session.query(users.id("user-1")).execute()) { Record user = stream.getFirstRecord(); name = user.getString("name");}key, meta, bins = client.get(key)name = bins["name"]stream = await session.query(users.id("user-1")).execute()row = await stream.first_or_raise()user = row.record_or_raise()name = user.bins.get("name")stream.close()Update
client.put(null, key, new Bin("visits", 1), new Bin("updated", true));session.update(users.id("user-1")) .bin("visits").setTo(1) .bin("updated").setTo(true) .execute();client.put(key, {"visits": 1, "updated": True})await ( session.update(users.id("user-1")) .bin("visits").set_to(1) .bin("updated").set_to(True) .execute())Delete
client.delete(null, key);session.delete(users.id("user-1")).execute().close();client.remove(key)stream = await session.delete(key=users.id("user-1")).execute()stream.close()Query with filters
Statement stmt = new Statement();stmt.setNamespace("test");stmt.setSetName("users");stmt.setFilter(Filter.range("age", 21, 100));
RecordSet rs = client.query(null, stmt);while (rs.next()) { Record record = rs.getRecord(); // process record}import com.aerospike.client.sdk.Record;import com.aerospike.client.sdk.RecordResult;import com.aerospike.client.sdk.RecordStream;
RecordStream stream = session.query(users) .where("$.age >= 21") .execute();stream.forEach((RecordResult result) -> { if (result.isOk()) { Record row = result.recordOrThrow(); if (row != null) { // process record } }});stream.close();query = client.query("test", "users")query.where(aerospike.predicates.between("age", 21, 100))
for record in query.results(): # process recordstream = await session.query(users).where("$.age >= 21").execute()async for row in stream: row.record_or_raise() pass # process the returned recordstream.close()Migration strategy
Option 1: gradual migration
- Add Developer SDK dependency alongside classic
- Create new features with Developer SDK
- Migrate existing code incrementally
- Remove classic client when migration complete
Option 2: full migration
- Create a feature branch
- Replace all classic client calls with Developer SDK equivalents
- Run comprehensive tests
- Deploy with confidence
What’s not supported (yet)
Some advanced features from the classic client are not yet available in the Developer SDK SDK:
- Admin operations (cluster management)
- HyperLogLog
- GeoJSON queries
- Some complex expression in the AEL
For these features, continue using the classic client alongside Developer SDK.
Next steps
- Quickstart — Get started with Developer SDK
- AEL Queries — Learn the query syntax
- Error Handling — Understand error recovery