Skip to content

Rest API

Cedrick Lunven edited this page Sep 9, 2021 · 7 revisions

AstraClient and Stargate initializations have been detailed on the Home page. Moving forward the sample code will reuse those classes but do not initialized them.

The Stargate REST API provides CRUD operations on top of Cassandra objects (tables, UDT, records). It was implemented to create an stateless absraction layer on top of Cassandra Query Language (CQL)

Related Api Reference documentation and endpoints can be found there

ApiDataClient Initialization

Class ApiDataClient is the core class to work with Rest DATA. There are multiple ways to retrieve or initialize it.

// Option1. Given an astraClient
ApiDataClient client1 = astraClient.apiStargateData();
ApiDataClient client2 = astraClient.getStargateClient().apiRest();

// Option 2. Given a StargateClient
ApiDataClient client3 = stargateClient.apiRest();

// Option 3. Constructors
ApiDataClient client4_Astra    = new ApiDataClient("http://api_endpoint", "apiToken");
ApiDataClient client5_Stargate = new ApiDataClient("http://api_endpoint", 
  new TokenProviderDefault("username", "password", "http://auth_endpoint");

From now, in another samples, we will use the variable name apiClient as our working instance of ApiDataClient

Working with keyspaces

DataApiIntegrationTest is the main unit test for this API and could be use as reference code

✅. Lists available Keyspace Names

Stream<String> keyspaceNames = apiClient.keyspaceNames();

✅. Lists available Keyspaces

Stream<Keyspace> keyspaces = apiClient.keyspaces();

✅. Find a keyspace by its id

Optional<Keyspace> ns1 = apiClient.keyspace("ks1").find();

✅. Test if a keyspace exists

apiClient.keyspace("ks1").exist();

✅. Create a new keyspace

🚨 As of Today, namespaces and keyspaces creations in ASTRA are available only at the DevOps API level but work in in a StandAlone stargate deployment

// Create a keyspace with a single DC dc-1
DataCenter dc1 = new DataCenter("dc-1", 1);
apiClient.keyspace("ns1").create(dc1);

// Create a keyspace providing only the replication factor
apiClient.keyspace("ns1").createSimple(3);

✅. Delete a keyspace

🚨 As of today namespaces and keyspaces creations are not available in ASTRA but work as expected with standalone stargate.

apiClient.keyspace("ns1").delete();

ℹ️ Tips

You can simplify the code by assigning apiClient.keyspace("ks1") to a KeyspaceClient variable as shown below:

KeyspaceClient ks1Client = astraClient.apiStargateData().keyspace("ns1");
        
// Create if not exist
if (!ks1Client.exist()) {
  ks1Client.createSimple(3);
}
        
// Show datacenters where it lives
ks1Client.find().get().getDatacenters()
         .stream().map(DataCenter::getName)
         .forEach(System.out::println); 
        
// Delete 
ks1Client.delete();

Working with Tables

✅. Lists available tables in a keyspace

// We can create a local variable to shorten the code.
KeyspaceClient ks1Client = apiClient.keyspace("ks1");

// List names of the tables
Stream<String> tableNames = ks1Client.tableNames();

// List Definitions of the table (primarykey...)
Stream<TableDefinition> tableDefinitions = ks1Client.tables();

✅. Check if a table exists

TableClient tableXClient = apiClient.keyspace("ks1").table("table_x");
boolean colExist = tableXClient.exist();

✅. Retrieve a table definition from its name

Optional<TableDefinition> = apiClient.keyspace("ks1").table("table_x").find();

✅. Create a table

A TableDefinition is expected to create a table. It will detailed all columns and their specific natures (partition key and clustering columns). It can be pretty verbose as such a Builder is provided TableCreateBuilder.

// Using a builder to define the table structure
apiClient.keyspace("ks1").table("table_x").create(
  CreateTable.builder()
    .ifNotExist(true)
    .addPartitionKey("genre", "text")
    .addClusteringKey("year", "int", Ordering.DESC)
    .addClusteringKey("title", "text", Ordering.ASC)
    .addColumn("upload", "timestamp")
    .addColumn("tags", "set<text>")
    .addColumn("frames", "list<int>")
    .addColumn("tuples", "tuple<text,text,text>")
    .addColumn("formats", "frozen<map <text,text>>")
    .build()
);

✅. Update Table options

// You can change the TTL and some clustering columns informations
apiClient.keyspace("ks1").table("table_x")
         .updateOptions(new TableOptions(25, null));

✅. Delete a table

apiClient.keyspace("ks1").table("table_x").delete();

Working with Columns

✅. Lists available columns in a Table

// Get column Names
Stream<String> columnNames = apiClient.keyspace("ks1").table("table_x").columnNames();

// Get Column Definition
Stream<ColumnDefinition> columns = apiClient.keyspace("ks1").table("table_x").columns();

✅. Check if columns exists

boolean colExist = apiClient.keyspace("ks1").table("table_x").column("col1").exist();

✅. Retrieve a columns from its name

Optional<ColumnDefinition> col = apiClient
   .keyspace("ks1")
   .table("table_x")
   .column("col1")
   .find();

✅. Create an new Column

apiClient.keyspace("ks1")
         .table("table_x")
         .column("col1")
         .create(new ColumnDefinition("col", "text"));

✅. Rename a column

apiClient.keyspace("ks1")
         .table("table_x")
         .column("col1")
         .rename("col2");

✅. Delete a column

apiClient.keyspace("ks1")
         .table("table_x")
         .column("col1").delete();

Working with Indexes

✅. Lists available indexes in a Table

// Get column Names
Stream<String> indexesNames = apiClient.keyspace("ks1").table("table_x").indexesNames();

// Get Column Definition
Stream<IndexDefinition> indexes = apiClient.keyspace("ks1").table("table_x").indexes();

✅. Check if index exists

boolean colExist = apiClient.keyspace("ks1").table("table_x").index("idx1").exist();

✅. Retrieve a index from its name

Optional<IndexDefinition> idxDef = apiClient
   .keyspace("ks1")
   .table("table_x")
   .index("idx1")
   .find();

✅. Create an new Index

CreateIndex cIdx = CreateIndex.builder()
  .ifNotExist(true)
  .name("idx1").column("title")
  .sasi()
  .build();
apiClient.keyspace("ks1")
         .table("table_x")
         .index("idx1")
         .create(cIdx);

✅. Delete an Index

apiClient.keyspace("ks1")
         .table("table_x")
         .index("idx1")
         .delete();

Working with User Defined Types

✅. Lists available types in a keyspace

// We can create a local variable to shorten the code.
KeyspaceClient ks1Client = apiClient.keyspace("ks1");

// List names of the types
Stream<String> typeNames = ks1Client.typeNames();

// List Definitions of the type (attributes...)
Stream<TypeDefinition> typeDefinitions = ks1Client.types();

✅. Check if a type exists

TypeClient typeVideo = apiClient.keyspace("ks1").type("videos");
boolean colExist = typeVideo.exist();

✅. Retrieve a type definition from its name

Optional<TypeDefinition> = apiClient.keyspace("ks1").type("videos").find();

✅. Create a type

// Using a builder to define the table structure
CreateType ct = new CreateType("videos", true);
ct.getFields().add(new TypeFieldDefinition("city", "text"));
ct.getFields().add(new TypeFieldDefinition("zipcode", "int"));
ct.getFields().add(new TypeFieldDefinition("street", "text"));
ct.getFields().add(new TypeFieldDefinition("phone", "list<text>"));
apiClient.keyspace("ks1").type("videos").create(ct);

✅. Update a type

UpdateType ut= new UpdateType();
// Fields to add
ut.getAddFields().add(new TypeFieldDefinition("country","text" ));
// Fields to rename
ut.getRenameFields().add(new TypeFieldUpdate("city", "town"));
address.update(ut);

✅. Delete a type

apiClient.keyspace("ks1").type("videos").delete();

Working with DATA