Migrate to the Data API from the Stargate APIs
The legacy Stargate APIs were deprecated for Astra DB Serverless as of September 2024 with end-of-life (EOL) scheduled for the end of 2025.
Use this page to help you migrate your applications off of the Stargate APIs before EOL.
Stargate API migration paths
Alternatives to the Stargate APIs include the Data API, Apache Cassandra® drivers, or the CQL shell.
The following table summarizes the recommended migration paths for each Stargate API:
Stargate API | Recommended migration path | Migration guide |
---|---|---|
Document API |
Use the Data API |
|
REST API |
Use the Data API |
|
GraphQL API |
Use the Data API |
|
gRPC API |
Use Cassandra drivers |
Migrate from the Stargate Document API
If you use the Stargate Document API, DataStax recommends that you modify your code to use the Data API’s commands for working with collections and documents.
Transform and migrate your data
The Data API supports only Serverless (Vector) databases.
If your data is stored in a Serverless (Non-Vector) database, you must move it to a Serverless (Vector) database before migrating your application code to use the Data API. This is required even if your database has no vector data.
Furthermore, because Data API collections aren’t equivalent to Document API collections, you must extract the JSON documents from your Document API collections, verify that the JSON is compliant with the Data API, and then insert the documents into new Data API collections.
The following guidance explains the general process for migrating your data from a Document API collection to a Data API collection. The examples provided aren’t exclusive. The tools and methods you use depend on the amount of data and your application’s dependency on the JSON schema. For example, extracting thousands of documents can be time consuming with the Document API’s page limit of 20 documents. |
-
Extract your JSON documents.
For example, you can use the Document API to read documents in batches of 20:
curl -sS -L -X GET "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections/COLLECTION_NAME?page-size=20" \ --header "X-Cassandra-Token: $AUTH_TOKEN" \ --header "Content-Type: application/json"
Then, write each batch of returned documents to a JSON file, discarding any part of the response that isn’t part of a document, such as
pageState
. -
Modify your documents for compliance with the Data API, including valid data types in collections, the
_id
field, and Data API limits.If you want to maintain your existing document ID values, make sure that you map each document’s UUID in your extracted JSON file to the
_id
field for the Data API.To illustrate this point, the following examples compare the same document as it would be represented in the Document API and the Data API. The document has an ID of
9195f8c9-1bd8-4ee5-b812-7075f9343331
. In the Document API, the document object is the key of the entire document object. In the Data API, the_id
field is part of the document object.-
Document API
-
Data API
"9195f8c9-1bd8-4ee5-b812-7075f9343331": { "reader": { "birthdate": "10-01-1980", "name": "Amy Smith", "reviews": [ { "book_title": "Moby Dick", "comment": "It was better than I thought.", "rating": 4, "review-date": "04-25-2002" }, { "book_title": "Pride and Prejudice", "comment": "It was just like the movie.", "rating": 2, "review_date": "12-02-2002" } ], "user_id": "12345" } }
{ "_id": "9195f8c9-1bd8-4ee5-b812-7075f9343331", "reader": { "birthdate": "10-01-1980", "name": "Amy Smith", "reviews": [ { "book_title": "Moby Dick", "comment": "It was better than I thought.", "rating": 4, "review-date": "04-25-2002" }, { "book_title": "Pride and Prejudice", "comment": "It was just like the movie.", "rating": 2, "review_date": "12-02-2002" } ], "user_id": "12345" } }
For more information, see No user-defined schema enforcement.
-
-
Create a collection in a Serverless (Vector) database.
-
Write your extracted and transformed JSON documents to the new collection.
You can insert data in the Astra Portal or programmatically. For an example of a script that uses the Data API to load documents from a JSON file, see the Astra DB Serverless quickstart for collections.
Next, migrate your code to use the Data API, using the guidance in the following sections.
Connect with the Data API
The Data API and the Stargate Document API connect to Astra DB in similar ways:
- Connection methods
-
You can connect over HTTP or use a client.
If you use the Document API’s Node.js client, consider using the Data API’s TypeScript client.
- Base URLs
-
The base URL is the same:
https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com
If you use a Data API client, you don’t directly specify the base URL.
If you send requests over HTTP, be aware that some database management operations use the DevOps API, which has a different base URL.
- Authentication tokens
-
The Data API uses application tokens for authentication.
The token format is
AstraCS:
followed by a unique token string.You can create application tokens in the Astra Portal or with the DevOps API.
Application tokens must have the required permissions for the commands you want to run. For database reads and writes, a role like Database Administrator is sufficient. Some database management operations require a higher-level role, such as Organization Administrator.
For more information, see Get started with the Data API.
Work with namespaces, keyspaces, and collections
This section compares how you interact with namespaces/keyspaces and collections using the Document API and the Data API.
- Data API collections are different from Document API collections
-
Like the Document API, the Data API stores documents in collections. Collections are stored in keyspaces, which are equivalent to what the Document API refers to as either namespaces or keyspaces.
Data API collections, which exist in Astra DB Serverless (Vector) databases, are functionally and structurally different from Document API collections.
Before migrating your code to the Data API, you must load your data into a Data API-compatible collection. For more information, see Transform and migrate your data.
- Databases have a collection limit
-
Each keyspace can have multiple collections, but there is a limit on the total number of collections across an entire database, which is driven by the number of indexes.
- All fields are indexed by default
-
When you insert a document into a Data API collection, all fields are indexed by default.
If you want to customize the indexing behavior, you can enable selective indexing when you create a collection. However, selective indexing doesn’t restrict the specific fields that a document can have, and you can’t change the selective indexing behavior after you create the collection.
- No user-defined schema enforcement
-
The Data API has no equivalent to the Document API’s JSON schema specification endpoint (
/v2/namespaces/NAMESPACE/collections/COLLECTION/json-schema
). Any user-defined schema enforcement must be done in your application code prior to writing a document to a collection.Data API collections have dynamic schemas, and the schema isn’t strictly enforced. Each document in a Data API collection can have different fields, as long as the document adheres to the Data API limits, such as the maximum document size and maximum object depth, as well as the supported data types in collections.
Data API data types in collection are less specific than the Document API’s data types. For example, the Data API uses the expansive
Number
type for all number values, rather than specific types likeint
,double
, andfloat
. As with the overall schema, you must enforce any data type restrictions or format requirements in your application code. - Eventual consistency in multi-region databases
-
The Data API has no equivalent to the Stargate Document API’s
replicas
setting because this setting isn’t configured by the Data API in Astra DB.Astra DB enforces data consistency across regions of multi-region databases. While reading or writing to a local region can reduce latency, all changes are eventually replicated across all regions of a multi-region database. For more information, see Replicas and consistency levels.
- Collection settings are immutable
-
After you create a collection, you cannot change its settings.
At minimum, you must specify the collection’s name and the keyspace where you want to create it. This creates a collection that cannot store vector data.
If you want to enable vector search features, apply selective indexing, or change the default ID format, you must specify those settings when you create the collection. For more information and examples, see Create a collection.
Command compatibility matrix for keyspaces and collections
The following table compares Document API keyspace and collection endpoints with their equivalent Data API commands.
This table is based on HTTP endpoints. If you use a client, your scripts must include additional commands as needed to work with certain endpoints. For example, keyspace administration requires a Database Admin object.
Operation | Document API endpoint | Data API reference |
---|---|---|
Create a namespace (keyspace) |
|
|
Get a list of namespaces (keyspaces) |
|
|
Delete a namespace (keyspace) |
|
|
Create a collection |
|
|
Upgrade a collection to support SAI |
|
No equivalent in the Data API because Data API collections inherently use SAI. For more information, see Indexes in collections. |
Get a list of collections |
|
|
Delete a collection |
|
Collection code examples
The following code samples compare some Document API collection operations with the equivalent Data API commands over HTTP. For more information and equivalencies for all Document API keyspace and collection operations, see Command compatibility matrix for keyspaces and collections.
Document API collections are functionally and structurally different from Data API collections. These examples compare related operations, but the underlying collection constructs aren’t identical. |
-
Document API
-
Data API
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"name": "COLLECTION_NAME"
}'
The following example creates a basic, non-vector collection that cannot store vector data or perform advanced searches:
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"createCollection": {
"name": "COLLECTION_NAME",
"options": {}
}
}'
If you want to store vector data, perform vector search, or use other advanced search patterns, you must configure those settings when you create the collection.
For more examples and information about vector-enabled collections and other collection settings, see Create a collection.
-
Document API
-
Data API
curl -sS -L -X GET "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"findCollections": {
"options": {
"explain": false
}
}
}'
"explain": false
prompts the Data API to return only the collection names.
If true, the Data API returns collection names and settings.
-
Document API
-
Data API
curl -sS -L -X DELETE "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections/COLLECTION_NAME" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"deleteCollection": {
"name": "COLLECTION_NAME"
}
}'
Write, update, and delete documents
This section compares how you write, update, and delete documents with the Document API and the Data API.
- Create a collection before inserting documents
-
With the Data API, you must create a collection before inserting documents into it; you cannot create a collection and insert a document in the same request.
- All document operations use the POST method with a consistent endpoint
-
All Data API requests use the
POST
method with the desired command and command options specified in the request body.Additionally, the Data API specifies only the keyspace and collection in the endpoint path. All other command parameters are specified in the request body. As long as you are working within the same keyspace and collection, the endpoint path remains the same for all document-level operations.
This is in contrast to the Document API, which uses various path parameters, query parameters, body parameters, and methods.
- Document IDs are automatically generated if omitted
-
All documents in a Data API collection have an
_id
field, which is equivalent to the identifiers for document objects in the Document API.You can specify the
_id
field when you insert a document, or you can omit it and let the Data API automatically generate an_id
for you. The default auto-generated_id
format depends on the collection’s settings. For more information, see Document IDs. - The Data API doesn’t support
profile
,ttl
, orraw
-
The Data API doesn’t provide equivalents to the Document API’s
profile
,ttl
, orraw
options.With respect to
raw
, some Data API commands offer options to manipulate the content of responses. When available, these options are described in the command’s reference documentation. - The Data API supports more update operators
-
The Data API supports more update operators than the Document API, and the Data API’s
$push
operator is more dynamic than the Document API’s$push
operator. For information about the available operators, see Update operators for collections.Additionally, the Data API has no equivalent to the
GET /v2/schemas/namespaces/NAMESPACE/functions
endpoint. Instead, you include update operators directly in the request body of your update and replace commands. - Upserts don’t occur by default
-
With the Document API,
PATCH
requests automatically perform an upsert if no matching document is found.In contrast, Data API commands to update or replace documents don’t perform an upsert by default. If you want a specific request to perform an upset, you can include the
upsert
parameter in the request body.
Command compatibility matrix for writing, updating, and deleting documents
The following table compares Document API operations to write, update, and delete documents with their equivalent Data API commands.
This table is based on HTTP endpoints. If you use a client, your scripts must include additional commands as needed to work with certain endpoints. For example, document-level operations require a Collection object.
Operation | Document API endpoint | Data API reference |
---|---|---|
Write a document with an automatically generated ID |
|
|
Write a document with a specific ID |
|
|
Batch write with automatically generated IDs |
|
|
Batch write with a specific ID |
|
|
Replace an entire document |
|
|
Update part of a document |
|
|
Update multiple documents |
||
Use push and pop to update arrays |
|
|
Delete a document by ID |
|
|
Delete a document matching a |
|
|
Delete multiple documents |
||
Delete part of a document |
|
Use |
Code examples for writing, updating, and deleting documents
The following code samples compare some Document API operations to write, update, and delete documents with the equivalent Data API commands over HTTP. For more information and equivalencies for all such operations, see Command compatibility matrix for writing, updating, and deleting documents.
-
Document API
-
Data API
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections/COLLECTION_NAME" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"reader": {
"birthdate": "10-01-1980",
"name": "Amy Smith",
"reviews": [
{
"book_title": "Moby Dick",
"comment": "It was better than I thought.",
"rating": 4,
"review_date": "04-25-2002"
},
{
"book_title": "Pride and Prejudice",
"comment": "It was just like the movie.",
"rating": 2,
"review_date": "12-02-2002"
}
],
"user_id": "12345"
}
}'
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/COLLECTION_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"insertOne": {
"document": {
"reader": {
"birthdate": "10-01-1980",
"name": "Amy Smith",
"reviews": [
{
"book_title": "Moby Dick",
"comment": "It was better than I thought.",
"rating": 4,
"review_date": "04-25-2002"
},
{
"book_title": "Pride and Prejudice",
"comment": "It was just like the movie.",
"rating": 2,
"review_date": "12-02-2002"
}
],
"user_id": "12345"
}
}
}
}'
-
Document API
-
Data API
curl -sS -L -X PUT "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections/COLLECTION_NAME/DOCUMENT_ID" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"reader": {
"birthdate": "10-01-1980",
"name": "Amy Smith",
"reviews": [
{
"book_title": "Moby Dick",
"comment": "It was better than I thought.",
"rating": 4,
"review_date": "04-25-2002"
},
{
"book_title": "Pride and Prejudice",
"comment": "It was just like the movie.",
"rating": 2,
"review_date": "12-02-2002"
}
],
"user_id": "12345"
}
}'
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/COLLECTION_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"insertOne": {
"document": {
"_id": "DOCUMENT_ID"",
"reader": {
"birthdate": "10-01-1980",
"name": "Amy Smith",
"reviews": [
{
"book_title": "Moby Dick",
"comment": "It was better than I thought.",
"rating": 4,
"review_date": "04-25-2002"
},
{
"book_title": "Pride and Prejudice",
"comment": "It was just like the movie.",
"rating": 2,
"review_date": "12-02-2002"
}
],
"user_id": "12345"
}
}
}
}'
-
Document API
-
Data API
curl -sS -L -X PUT "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections/COLLECTION_NAME/DOCUMENT_ID" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json" \
--data '{ NEW_DATA_FOR_ENTIRE_DOCUMENT }'
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/COLLECTION_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"findOneAndReplace": {
"filter": {
"_id": "DOCUMENT_ID"
},
"replacement": {
NEW_DATA_FOR_ENTIRE_DOCUMENT
}
}
}'
-
Document API
-
Data API
curl -sS -L -X PATCH "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections/COLLECTION_NAME/DOCUMENT_ID" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json" \
--data ' {
"color": "green"
}'
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/COLLECTION_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"updateOne": {
"filter": { "_id": "DOCUMENT_ID" },
"update": { "$set": { "color": "green" } }
}
}'
-
Document API
-
Data API
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections/COLLECTION_NAME/DOCUMENT_ID/FIELD_NAME/function" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json" \
--data ' {
"operation": "$push", "value": "NEW_VALUE_TO_APPEND"
}'
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/COLLECTION_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"updateOne": {
"filter": { "_id": "DOCUMENT_ID" },
"update": {
"$push": {
"FIELD_NAME": {
"$each": [ "NEW_VALUE" ],
"$position": INDEX_POSITION_TO_INSERT_NEW_VALUE
}
}
}
}
}'
-
Document API
-
Data API
curl -sS -L -X DELETE "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections/COLLECTION_NAME/2545331a-aaad-45d2-b084-9da3d8f4c311" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/COLLECTION_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"deleteOne": {
"filter": { "_id": "2545331a-aaad-45d2-b084-9da3d8f4c311" }
}
}'
-
Document API
-
Data API
curl -sS -L -X DELETE "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections/COLLECTION_NAME/DOCUMENT_ID/FIELD_OR_PATH" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
With the Data API, you use the $unset
operator in an update command to remove a field from a document:
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/COLLECTION_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"updateOne": {
"filter": { "_id": "2545331a-aaad-45d2-b084-9da3d8f4c311" },
"update": { "$unset": { "color": "" } }
}
}'
Read documents
This section compares how you read documents with the Data API and the Document API.
- The Data API uses filter operators in filter clauses
-
Like the Document API, the Data API finds documents that match a filter operator expression. The Data API supports all of the Document API’s predicates and Boolean operators, as well as multi-field filters and filters on nested fields. However, the Data API doesn’t have a
$selectivity
operator. For more information and examples, see Filter operators for collections.While these operators have similar effects on the results, the requests have different structures. The Document API passes filters entirely in the
where
query parameter, while the Data API uses a filter clause in the request body. For example, compare the following requests to find a document where thereader.name
field contains exactly"Amy Smith"
.-
Document API
-
Data API
With the Document API, the entire filter is expressed in the request path, and you must apply URL encoding and escaping to any path-breaking characters, such as spaces, periods, and commas:
curl -sS -L -X GET "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections/COLLECTION_NAME?where={"reader.name":{"$eq":"Amy%20Smith"}}" \ --header "X-Cassandra-Token: $AUTH_TOKEN" \ --header "Content-Type: application/json"
With the Data API, the filter is expressed in the request body. You don’t need to modify the query string, and it can be easier for your developers to understand complex, nested filters.
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/COLLECTION_NAME" \ --header "Token: APPLICATION_TOKEN" \ --header "Content-Type: application/json" \ --data '{ "findOne": { "filter": { "reader.name": { "$eq": "Amy Smith" } } } }'
-
- No wildcards in filters
-
The Data API doesn’t allow wildcards (
*
) in filters.You must explicitly define the fields and values that you want to query. However, you can use filter operators to create multi-field and multi-value filters, such as ranges, multiple
$and
conditions, and multiple$or
conditions. - Use projections to extract or return specific fields or values
-
With the Document API, you can use the
fields
query parameter or path parameters to retrieve values of specific fields, such as?fields=["field1","field2"]
.In contrast, the Data API uses projections to specify the returned fields, including slices of arrays. Projections are specified in the request body, such as
"projection": {"field1": true, "field2": true}
. Projections can be inclusive or exclusive, use wildcards, and apply special handling to reserved fields. For more information, see Projections for collections. - Pagination still applies
-
Both the Document API and the Data API apply pagination to read requests. Page size and availability of pagination depend on the type of request. For more information, see Find documents: Result and Find documents: Iterate over found documents.
- The Data API supports vector search, hybrid search, sorting, skipping, and response limits
-
The Data API provides additional
sort
,skip
, andlimit
options for read requests.You can use sort clauses for ascending/descending sorting, similarity search, and hybrid search. For more information, see Sort clauses for collections.
For information about
skip
andlimit
, see Find documents: Parameters.
Command compatibility matrix for reading documents
The following table compares Document API operations that read documents with their equivalent Data API commands.
This table is based on HTTP endpoints. If you use a client, your scripts must include additional commands as needed to work with certain endpoints. For example, document-level operations require a Collection object.
Operation | Document API endpoint | Data API reference |
---|---|---|
Retrieve a document by ID |
|
|
Retrieve a document with a |
|
|
Retrieve multiple documents with a |
|
|
Retrieve specific fields or values from a document |
|
Use a projection when finding one or more documents |
Retrieve all documents |
|
Use an empty filter to find all documents While this is possible with the Data API, it is inefficient and not recommended for large collections. DataStax recommends using a filter or sort clause for any Data API read request. |
Document API code examples for reading documents
The following code samples compare some Document API operations that read documents with the equivalent Data API commands over HTTP. For more information and equivalencies for all such operations, see Command compatibility matrix for reading documents.
-
Document API
-
Data API
curl -sS -L -X GET "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections/COLLECTION_NAME/2545331a-aaad-45d2-b084-9da3d8f4c311" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/COLLECTION_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"findOne": {
"filter": { "_id": "2545331a-aaad-45d2-b084-9da3d8f4c311" }
}
}'
-
Document API
-
Data API
curl -sS -L -X GET "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections/COLLECTION_NAME?where={"number_of_pages":{"$gt":300}}" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/COLLECTION_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"find": {
"filter": { "number_of_pages": { "$gt": 300 } }
}
}'
-
Document API
-
Data API
curl -sS -L -X GET "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/namespaces/NAMESPACE_NAME/collections/COLLECTION_NAME?where={"number_of_pages":{"$gt":300}}&fields=["is_checked_out","title"]" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/COLLECTION_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"find": {
"filter": { "number_of_pages": { "$gt": 300 } },
"projection": { "is_checked_out": true, "title": true }
}
}'
Migrate from the Stargate REST API
If you use the Stargate REST API, DataStax recommends that you modify your code to use the Data API’s commands for working with tables. While the Data API and the Stargate REST API aren’t identical, the JSON structure of the Data API commands, particularly over HTTP, has parallels to the REST API commands.
Alternatively, if you prefer a CQL-first approach or your application requires specific CQL functionality that isn’t supported by the Data API, then you can use a Cassandra driver or the standalone CQL shell. These options aren’t covered in this migration guide.
Verify database compatibility
Tables created with the Stargate REST API are compatible with the Data API without requiring any schema changes. However, the Data API supports tables in Serverless (Vector) databases only.
If your data is stored in a Serverless (Non-Vector) database, you must move it to a Serverless (Vector) database before migrating your application code to use the Data API. This is required even if your database has no vector data.
If you don’t want to move your data, then you must consider a CQL-based alternative, such as a Cassandra driver.
Connect with the Data API
The Data API and the Stargate REST API connect to Astra DB in similar ways:
- Connection methods
-
You can connect over HTTP or use a client (recommended).
For example, if you use the REST API’s Node.js client, consider using the Data API’s TypeScript client.
- Base URLs
-
The base URL is the same:
https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com
If you use a Data API client, you don’t directly specify the base URL.
If you send requests over HTTP, be aware that some database management operations use the DevOps API, which has a different base URL.
- Authentication tokens
-
The Data API uses application tokens for authentication.
The token format is
AstraCS:
followed by a unique token string.You can create application tokens in the Astra Portal or with the DevOps API.
Application tokens must have the required permissions for the commands you want to run. For database reads and writes, a role like Database Administrator is sufficient. Some database management operations require a higher-level role, such as Organization Administrator.
For more information, see Get started with the Data API.
Work with keyspaces and tables
The Stargate REST API and the Data API’s table commands both facilitate interactions with CQL tables, which require a fixed schema and are stored in keyspaces. Each keyspace can have multiple tables.
This section compares how you interact with keyspaces and tables using the Data API and the REST API.
- The Data API doesn’t support all CQL types, including UDTs
-
The Data API supports a subset of CQL data types, and it offers partial support for some unsupported types.
For supported types, see Data types in tables.
Unsupported types, formats, and modifiers include:
-
User-defined types (UDTs)
-
Time To Live (TTL)
-
Column timestamps
-
Frozen
-
Static
-
Tuple
The following types have limited support:
For more information, see Migrate to the Data API from CQL.
-
- The Data API doesn’t support
static
,defaultTimeToLive
, orraw
-
The Data API doesn’t provide equivalents to the REST API’s
static
,defaultTimeToLive
, orraw
options.With respect to
raw
, some Data API commands offer options to manipulate the content of responses. When available, these options are described in the command’s reference documentation.If your tables contain TTLs or static values, see Support for existing tables.
- The Data API doesn’t allow retyping or renaming of tables and columns
-
Dropping a column or table deletes any data stored in the dropped column or table. If you need to retype or rename a column or table, consider exporting the data before dropping the column or table.
With the Data API, you cannot change a column’s type, rename a column, or rename a table. Instead, you can drop and recreate the column or table. For more information, see Alter a table.
- Indexed column names must use snake case
-
You must use snake case for the names of any indexed columns, such as
column_name
. Don’t use camel case, such ascolumnName
. - Eventual consistency in multi-region databases
-
The Data API has no equivalent to the Stargate REST API’s
replicas
setting because this setting isn’t configured by the Data API in Astra DB.Astra DB enforces data consistency across regions of multi-region databases. While reading or writing to a local region can reduce latency, all changes are eventually replicated across all regions of a multi-region database. For more information, see Replicas and consistency levels.
Command compatibility matrix for keyspaces and tables
The following table compares REST API keyspace and table endpoints with their equivalent Data API commands.
This table is based on HTTP endpoints. If you use a client, your scripts must include additional commands as needed to work with certain endpoints. For example, keyspace administration requires a Database Admin object.
Operation | REST API endpoint | Data API reference |
---|---|---|
Create a keyspace |
|
|
Get a list of keyspaces |
|
|
Delete a keyspace |
|
|
Create a table |
|
|
Get schemas for all tables |
|
|
Get the schema for one table |
|
No equivalent in the Data API. Instead, use List table metadata, and then extract the desired table object from the response. |
Get the schema for one or more columns |
|
No equivalent in the Data API. Instead, use List table metadata, and then extract the desired column information from the response. |
Replace the schema for a table |
|
The Data API doesn’t allow retyping or renaming of tables and columns |
Retype or rename a column |
|
The Data API doesn’t allow retyping or renaming of tables and columns |
Add or remove columns |
|
|
Delete a table |
|
Code examples for tables
The following code samples compare some REST API table operations with the equivalent Data API commands over HTTP. For more information and equivalencies for all REST API keyspace and table operations, see Command compatibility matrix for keyspaces and tables.
-
REST API
-
Data API
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/schemas/keyspaces/KEYSPACE_NAME/tables" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
"name": "TABLE_NAME",
"columnDefinitions":
[
{
"name": "COLUMN_NAME",
"typeDefinition": "COLUMN_TYPE"
},
{
"name": "COLUMN_NAME",
"typeDefinition": "COLUMN_TYPE"
},
{
"name": "COLUMN_NAME",
"typeDefinition": "COLUMN_TYPE"
}
],
"primaryKey":
{
"partitionKey": ["PARTITION_KEY_COLUMN_NAME"],
"clusteringKey": ["CLUSTERING_KEY_COLUMN_NAME"]
},
"tableOptions":
{
"clusteringExpression": [
{ "column": "CLUSTERING_KEY_COLUMN_NAME", "order": "ASC" }
]
}
}'
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"createTable": {
"name": "TABLE_NAME",
"definition": {
"columns": {
"COLUMN_NAME": {
"type": "COLUMN_TYPE"
},
"COLUMN_NAME": {
"type": "COLUMN_TYPE"
},
"COLUMN_NAME": {
"type": "COLUMN_TYPE"
}
},
"primaryKey": {
"partitionBy": [
"PARTITION_KEY_COLUMN_NAME"
],
"partitionSort": {
"CLUSTERING_KEY_COLUMN_NAME": 1
}
}
}
}
}'
-
REST API
-
Data API
curl -sS -L -X GET "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/schemas/keyspaces/KEYSPACE_NAME/tables" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"listTables": {
"options": {
"explain": true
}
}
}'
-
REST API
-
Data API
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/schemas/keyspaces/KEYSPACE_NAME/tables/TABLE_NAME/columns" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
"name": "COLUMN_NAME",
"typeDefinition": "COLUMN_TYPE",
"static": false
}'
The following example adds one column.
You can use this command to add multiple columns at once by passing all column definitions in the columns
object.
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/TABLE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"alterTable": {
"operation": {
"add": {
"columns": {
"COLUMN_NAME": "COLUMN_TYPE"
}
}
}
}
}'
-
REST API
-
Data API
curl -sS -L -X DELETE "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/schemas/keyspaces/KEYSPACE_NAME/tables/TABLE_NAME/columns/COLUMN_NAME" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
The following example deletes one column.
You can use this command to delete multiple columns at once by passing all column names in the columns
array.
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/TABLE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"alterTable": {
"operation": {
"drop": {
"columns": [ "COLUMN_NAME" ]
}
}
}
}'
-
REST API
-
Data API
curl -sS -L -X DELETE "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/schemas/keyspaces/KEYSPACE_NAME/tables/TABLE_NAME" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"dropTable": {
"name": "TABLE_NAME"
}
}'
Work with indexes
This section compares how you manage table indexes with the Data API and the Stargate REST API.
-
As with all CQL tables, primary key columns are automatically indexed. It is a best practice to index any non-primary key columns that you want to query on.
-
With the Data API, you must use snake case for the names of any indexed columns, such as
column_name
. -
The Data API doesn’t support indexes on maps, lists, or sets.
-
The Data API has no equivalent to the REST API’s
type
option for indexes because this option isn’t relevant to Astra DB.
Command compatibility matrix for indexes
The following table compares REST API index endpoints with their equivalent Data API commands.
This table is based on HTTP endpoints. If you use a client, your scripts must include additional commands as needed to work with certain endpoints. For example, keyspace administration requires a Database Admin object.
Operation | REST API endpoint | Data API reference |
---|---|---|
Create an index |
|
|
Get index metadata |
|
|
Delete an index |
|
Index code examples
The following code samples compare some REST API index operations with the equivalent Data API commands over HTTP. For more information and equivalencies for all REST API index operations, see Command compatibility matrix for indexes.
-
REST API
-
Data API
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/schemas/keyspaces/KEYSPACE_NAME/tables/TABLE_NAME/indexes" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
"column": "COLUMN_NAME",
"name": "INDEX_NAME"
}'
The following command creates an SAI based on the specified column without character normalization:
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/TABLE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"createIndex": {
"name": "INDEX_NAME"",
"definition": {
"column": "COLUMN_NAME"
}
}
}'
If you want to normalize non-ASCII, Unicode, diacritic, and capitalized characters before creating the index, you can include options
in the index definition.
For more information, see Create an index.
Additionally, the Data API can create specialized vector indexes on columns of vector type. Vector indexes are required to perform vector searches on tables that contain vector data. For more information, see Create a vector index.
-
REST API
-
Data API
curl -sS -L -X GET "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/schemas/keyspaces/KEYSPACE_NAME/tables/TABLE_NAME/indexes" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/TABLE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"listIndexes": {
"options": {
"explain": true
}
}
}'
-
REST API
-
Data API
curl -sS -L -X DELETE "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/schemas/keyspaces/KEYSPACE_NAME/tables/TABLE_NAME/indexes/INDEX_NAME" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/TABLE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"dropIndex": {
"name": "INDEX_NAME"
}
}'
Read and write rows
This section compares how you read and write rows with the Data API and the Stargate REST API.
- Make sure your reads and writes are compliant with the Data API
-
Although the REST API and Data API have similar HTTP request bodies, the supported CQL operations, types, and expected syntax are different:
-
Migrate to the Data API from CQL: Learn about unsupported CQL types and operations, as well as compatibility for existing CQL tables that contain unsupported types.
-
Data types in tables: Learn the read and write format for different data types.
-
- All row operations use the POST method with a consistent endpoint
-
All Data API requests use the
POST
method with the desired command and command options specified in the request body.Additionally, the Data API specifies only the keyspace and table in the endpoint path. All other command parameters are specified in the request body. As long as you are working within the same keyspace and table, the endpoint path remains the same for all row-level operations.
This is in contrast to the REST API, which uses various path parameters and methods, with or without a request body.
- The Data API doesn’t support
raw
-
The Data API doesn’t provide an equivalent to the REST API’s
raw
option. However, some Data API commands offer options to manipulate the content of responses. When available, these options are described in the command’s reference documentation. - The Data API uses filter operators in filter clauses
-
Like the REST API, the Data API finds rows that match a filter operator expression.
For read operations, the Data API supports all of the REST API’s filter operations and multi-column filters. For update and delete operations, Data API restricts the filter operators and columns. For example, the command to delete one row is limited to the primary key columns and the
$eq
operator so that you can specify the unique row to delete. For more information and examples, see Filter operators for tables.While these operators have similar effects on the results, the requests have different structures. The REST API passes filters entirely in the
where
query parameter, while the Data API uses a filter clause in the request body. For example, compare the following requests to find a row where thefirstname
column contains exactly"Amy Smith"
.-
REST API
-
Data API
With the REST API, the entire filter is expressed in the request path, and you must apply URL encoding and escaping to any path-breaking characters, such as spaces, periods, and commas:
curl -sS -L -X GET "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/keyspaces/KEYSPACE_NAME/TABLE_NAME?where={"firstname":{"$eq":"Amy%20Smith"}}" \ --header "X-Cassandra-Token: $AUTH_TOKEN" \ --header "Content-Type: application/json"
With the Data API, the filter is expressed in the request body. You don’t need to modify the query string, and it can be easier for your developers to understand complex, nested filters.
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/TABLE_NAME" \ --header "Token: APPLICATION_TOKEN" \ --header "Content-Type: application/json" \ --data '{ "findOne": { "filter": { "firstname": { "$eq": "Amy Smith" } } } }'
-
- Use projections to return specific columns
-
With the REST API, you can use the
fields
query parameter to return specific columns, such as?fields=["column1","column2"]
.In contrast, the Data API uses projections to select the returned columns. Projections are specified in the request body, such as
"projection": {"column1": true, "column2": true}
, and they can use inclusive, exclusive, and wildcard expressions. For more information, see Projections for tables. - Pagination still applies
-
Both the REST API and the Data API apply pagination to read requests. Page size and availability of pagination depend on the type of request. For more information, see Find rows: Result and Find rows: Iterate over found rows.
- The Data API supports vector search, sorting, skipping, and response limits
-
The Data API provides
sort
,skip
, andlimit
options for read requests.You can use sort clauses for ascending/descending sorting and similarity search. For more information, see Sort clauses for tables.
For information about
skip
andlimit
, see Find rows: Parameters. - Updates and inserts are upserts
-
Any CQL
INSERT
orUPDATE
operation is also an upsert:-
An
INSERT
with the same primary key as an existing row overwrites the existing row with the given values. -
An
UPDATE
applied to a non-existent row creates a new row with the given values, unless theUPDATE
only unsets values.
-
Command compatibility matrix for rows
The following table compares REST API row operations with their equivalent Data API commands.
This table is based on HTTP endpoints. If you use a client, your scripts must include additional commands as needed to work with certain endpoints. For example, row-level operations require a Table object.
Operation | REST API endpoint | Data API reference |
---|---|---|
Write one row |
|
|
Batch write |
None |
|
Read rows with a |
|
|
Read rows by primary key |
|
Find rows with a |
Read specific columns |
|
Use a projection when finding one or more rows |
Read all rows |
|
Use an empty filter to find all rows While this is possible with the Data API, it is inefficient and not recommended for large tables. DataStax recommends using a filter or sort clause on indexed columns for any Data API read request. |
Update (or upsert) specific columns |
|
|
Replace (or upsert) an entire row |
|
Update a row and include all columns in the request |
Delete rows |
|
Row code examples
The following code samples compare some REST API row operations with the equivalent Data API commands over HTTP. For more information and equivalencies for all REST API row operations, see Command compatibility matrix for rows.
-
REST API
-
Data API
The following command writes a row that has two string columns and one list column:
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/schemas/keyspaces/KEYSPACE_NAME/TABLE_NAME" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"COLUMN_NAME": "VALUE",
"COLUMN_NAME": "VALUE",
"COLUMN_NAME": [ "LIST_VALUE", "LIST_VALUE" ]
}'
The following command writes a row that has two string columns and one list column. For more information about reading and writing specific data types, see Data types in tables.
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/TABLE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"insertOne": {
"document": {
"COLUMN_NAME": "VALUE",
"COLUMN_NAME": "VALUE",
"COLUMN_NAME": [ "LIST_VALUE", "LIST_VALUE" ]
}
}
}'
-
REST API
-
Data API
curl -sS -L -X GET "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/keyspaces/KEYSPACE_NAME/TABLE_NAME/PRIMARY_KEY_VALUE" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/TABLE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"find": {
"filter": { "PRIMARY_KEY_COLUMN": { "$eq": "PRIMARY_KEY_VALUE" } }
}
}'
-
REST API
-
Data API
curl -sS -L -X GET "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/keyspaces/KEYSPACE_NAME/TABLE_NAME?where={"firstname":{"$eq":"Amy%20Smith"}}" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/TABLE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"find": {
"filter": { "firstname": { "$eq": "Amy Smith" } }
}
}'
-
REST API
-
Data API
curl -sS -L -X GET "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/keyspaces/KEYSPACE_NAME/TABLE_NAME?where={"firstname":{"$eq":"Amy%20Smith"}}&fields=["lastname","email"]" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/TABLE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"find": {
"filter": { "firstname": { "$eq": "Amy Smith" } },
"projection": {"lastname": true, "email": true}
}
}'
-
REST API
-
Data API
curl -sS -L -X PATCH "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/keyspaces/KEYSPACE_NAME/TABLE_NAME/PRIMARY_KEY_VALUE" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"COLUMN_TO_UPDATE": "NEW_VALUE"
}'
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/TABLE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"updateOne": {
"filter": {
"PRIMARY_KEY_COLUMN": "PRIMARY_KEY_VALUE"
},
"update": {
"$set": {
"COLUMN_TO_UPDATE": "NEW_VALUE"
}
}
}
}'
-
REST API
-
Data API
curl -sS -L -X DELETE "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/v2/keyspaces/KEYSPACE_NAME/TABLE_NAME/PRIMARY_KEY_VALUE" \
--header "X-Cassandra-Token: $AUTH_TOKEN" \
--header "Content-Type: application/json"
curl -sS -L -X POST "https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com/api/json/v1/KEYSPACE_NAME/TABLE_NAME" \
--header "Token: APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"deleteOne": {
"filter": {
"PRIMARY_KEY_COLUMN": "PRIMARY_KEY_VALUE"
}
}
}'
Migrate from the Stargate GraphQL API
If you use the Stargate GraphQL API, DataStax recommends that you modify your code to use the Data API’s commands for working with tables. While the Data API doesn’t have a direct equivalent to GraphQL, the level of effort required to migrate your code to the Data API can be lower than that required to migrate to a Cassandra driver.
However, if you prefer a CQL-first approach or your application requires specific CQL functionality that isn’t supported by the Data API, then you must use a Cassandra driver or the standalone CQL shell. These options aren’t covered in this migration guide.
Verify database compatibility
Tables created with the Stargate GraphQL API are compatible with the Data API without requiring any schema changes. However, the Data API supports tables in Serverless (Vector) databases only.
If your data is stored in a Serverless (Non-Vector) database, you must move it to a Serverless (Vector) database before migrating your application code to use the Data API. This is required even if your database has no vector data.
If you don’t want to move your data, then you must consider a CQL-based alternative, such as a Cassandra driver.
Connect with the Data API
The Data API and the Stargate GraphQL API connect and send requests to Astra DB in similar ways:
- Connection methods
-
You can connect over HTTP or use a client.
If you favor GraphQL’s typing behavior, consider using the Data API’s TypeScript client.
- Authentication tokens
-
The Data API uses application tokens for authentication.
The token format is
AstraCS:
followed by a unique token string.You can create application tokens in the Astra Portal or with the DevOps API.
Application tokens must have the required permissions for the commands you want to run. For database reads and writes, a role like Database Administrator is sufficient. Some database management operations require a higher-level role, such as Organization Administrator.
For more information, see Get started with the Data API.
- Base URLs
-
The base URL is the same:
https://ASTRA_DB_ID-ASTRA_DB_REGION.apps.astra.datastax.com
If you use a Data API client, you don’t directly specify the base URL.
If you send requests over HTTP, be aware that some database management operations use the DevOps API, which has a different base URL.
- Endpoints and request syntax
-
The GraphQL API uses three core paths for schema creation (
/graphql-schema
), schema deployment (/graphql-admin
), and data operations (graphql/KEYSPACE
), and then sends GraphQL-formatted mutations and queries in the request body.Similarly, all Data API HTTP requests use the
POST
method with consistent paths, eitherapi/json/v1/KEYSPACE
orapi/json/v1/KEYSPACE/TABLE
, and all other operation details specified in the request body in JSON format.If you use a Data API client, the client builds the HTTP request for you.
To illustrate the difference in request structures, compare the following examples that create a table using CQL-first GraphQL, schema-first GraphQL, the Data API TypeScript client, and a Data API HTTP request.
-
CQL-first GraphQL API
-
Schema-first GraphQL API
-
Data API TypeScript client
-
Data API HTTP
This mutation defines the CQL schema for a table, including the keyspace, table name, primary key, column names, and data types. Executing this mutation creates the given table and the necessary GraphQL schema to interact with the table.
mutation { books: createTable( keyspaceName:"library", tableName:"books", partitionKeys: [ { name: "title", type: {basic: TEXT} } ] values: [ { name: "pages", type: {basic: INT} } { name: "genres", type: {basic: SET, info:{ subTypes: [ { basic: TEXT } ] } } } { name: "rating", type: {basic: FLOAT} } { name: "checked_out", type: {basic: BOOLEAN} } { name: "due_date", type: {basic: DATE} } ] ) }
This type definition describes an entire GraphQL schema, including the table definition and indexes:
type Books @key @cql_entity(name: "books") @cql_input { title: String! @cql_column(partitionKey: true) pages: Int @cql_index(name: "pages_idx") genres: [String] @cql_column(typeHint: "set<varchar>") rating: Float @cql_index(name: "rating_idx", target: VALUES) checked_out: Boolean due_date: Date }
The following code describes the CQL schema for a table, including the column names, data types, and primary key. In practice, this code would be part of a larger script that used the given table definition to create a table. That script would also specify the table name and keyspace.
const tableDefinition = Table.schema({ columns: { title: "text", pages: "int", genres: { type: "set", valueType: "text" }, rating: "float", checked_out: "boolean", due_date: "date", }, primaryKey: { partitionBy: ["title"], }, });
For an example of a JSON object that could be generated from a script containing this code, see the Data API HTTP tab.
The following JSON object would be passed in the request body of a Data API HTTP request. It includes the command (
createTable
) and all command parameters, such as the table name, column names, data types, and the primary key."createTable": { "name": "books", "definition": { "columns": { "title": { "type": "text" }, "pages": { "type": "int" }, "genres": { "type": "set", "valueType": "text" }, "rating": { "type": "float" }, "checked_out": { "type": "boolean" }, "due_date": { "type": "date" } }, "primaryKey": "title" } }
-
Schema operations
The Stargate GraphQL API and the Data API’s schema operations both facilitate interactions with CQL tables, which require a fixed schema and are stored in keyspaces. Each keyspace can have multiple tables.
This section compares how you interact with keyspaces, tables, and indexes using the Data API and the GraphQL API.
- No API schema deployment
-
The Data API doesn’t deploy any API-specific schema like a GraphQL schema, and it has no equivalent to the
graphql-admin
endpoint. If you prefer to take a schema-first approach in your code, consider using the Data API TypeScript client, although TypeScript typing isn’t a literal equivalent to GraphQL schemas.With the Data API, the term schema refers to a table’s CQL schema, which you define when you create or alter a table. This schema definition includes the keyspace, table name, column names, data types, and primary keys. It can also broadly refer to any indexes associated with the table, although these are not strictly part of the schema.
Tables you create with the GraphQL API have an underlying CQL schema, although you don’t interact with it as directly as you do with the Data API.
With the Data API, you cannot separate a table’s schema definition from the table itself. When you use the Data API to create a table, you issue one request that creates the table with your defined table schema, including column names, types, and the primary key. Likewise, to alter a table’s schema, you use the command to alter the table itself.
- The Data API doesn’t support all CQL types, including UDTs and tuples
-
The Data API supports a subset of CQL data types, and it offers partial support for some unsupported types. You must explicitly use the supported CQL types in your schema definitions.
For supported types, see Data types in tables.
Unsupported types, formats, and modifiers include:
-
User-defined types (UDTs)
-
Time To Live (TTL)
-
Column timestamps
-
Frozen
-
Static
-
Tuple
The following types have limited support:
For more information, see Migrate to the Data API from CQL.
-
- The Data API doesn’t allow retyping or renaming of tables and columns
-
Dropping a column or table deletes any data stored in the dropped column or table. If you need to retype or rename a column or table, consider exporting the data before dropping the column or table.
With the Data API, you cannot change a column’s type, rename a column, or rename a table. Instead, you can drop and recreate the column or table. For more information, see Alter a table.
- Don’t use camel case for indexed column names
-
You must use snake case for the names of any indexed columns, such as
column_name
. Don’t use camel case, such ascolumnName
.If your existing tables have indexed columns with camel case names, you might need to export your data and then reimport it to a new table with snake case column names. Alternatively, you might consider using a Cassandra driver instead of the Data API, particularly for long-lived or sensitive production databases.
- Don’t set the base index type with the Data API
-
The Data API has no equivalent to the GraphQL API’s
indexType
andclass
options for indexes because these options aren’t relevant to Astra DB. - No indexes on maps, lists, or sets
-
The Data API doesn’t support indexes on maps, lists, or sets.
- Eventual consistency in multi-region databases
-
The Data API has no equivalent to the Stargate GraphQL API’s
replicas
setting because this setting isn’t configured by the Data API in Astra DB.Astra DB enforces data consistency across regions of multi-region databases. While reading or writing to a local region can reduce latency, all changes are eventually replicated across all regions of a multi-region database. For more information, see Replicas and consistency levels.
Schema command compatibility matrix
The following table compares GraphQL API schema operations with their equivalent Data API commands.
This table is based on HTTP endpoints. If you use a client, your scripts must include additional commands as needed to work with certain endpoints. For example, keyspace administration requires a Database Admin object.
Operation | GraphQL API operation | Data API reference |
---|---|---|
Create a keyspace |
|
|
List keyspaces |
|
|
Drop a keyspace |
|
|
Create a table (object type) |
CQL-first: Schema-first: Include a |
|
List tables |
|
|
Add or drop columns |
CQL-first: Schema-first: Modify the table’s |
|
Replace the schema for a table |
CQL-first: Drop and recreate the table, or add and remove multiple columns Schema-first: Modify the table’s |
The Data API doesn’t allow retyping or renaming of tables and columns |
Retype or rename a column |
CQL-first: Drop and recreate the column Schema-first: Modify the table’s |
The Data API doesn’t allow retyping or renaming of tables and columns |
Drop a table |
CQL-first: Schema-first: Remove the table’s |
|
Create an index |
CQL-first: Schema-first: Include |
|
List indexes |
|
|
Drop an index |
CQL-first: Schema-first: Remove the |
Schema code examples
The following code samples compare some GraphQL API schema operations with the equivalent Data API commands over HTTP. For more information and equivalencies for all GraphQL API schema operations, see Schema command compatibility matrix.
-
CQL-first GraphQL
-
Schema-first GraphQL
-
Data API
mutation createTableBook {
book: createTable(
keyspaceName:"library",
tableName:"book",
partitionKeys: [
{ name: "title", type: {basic: TEXT} }
]
clusteringKeys: [
{ name: "author", type: {basic: TEXT} }
]
values: [
{ name: "genres", type: {basic: SET, info:{ subTypes: [ { basic: TEXT } ] } } }
]
)
}
type Book @key @cql_entity(name: "book") @cql_input {
title: String! @cql_column(partitionKey: true, name: "book_title")
author: String @cql_column(clusteringOrder: ASC)
genres: [String] @cql_index(name: "genres_idx", target: VALUES)
}
The keyspace is specified in the endpoint path.
"createTable": {
"name": "example_table",
"definition": {
"columns": {
"title": {
"type": "text"
},
"number_of_pages": {
"type": "int"
},
"author": {
"type": "text"
},
"genres": {
"type": "set",
"valueType": "text"
}
},
"primaryKey": {
"partitionBy": [
"title", "author"
]
}
}
}
-
CQL-first GraphQL
-
Schema-first GraphQL
-
Data API
mutation alterTableAddCols {
alterTableAdd(
keyspaceName:"library",
tableName:"book",
toAdd:[
{ name: "language", type: {basic: TEXT} }
{ name: "pub_year", type: {basic: INT} }
]
)
}
Modify the table’s type
definition in the GraphQL schema, and then redeploy the schema.
The keyspace and table are specified in the endpoint path.
"alterTable": {
"operation": {
"add": {
"columns": {
"language": "text",
"pub_year": "int"
}
}
}
}
-
CQL-first GraphQL
-
Schema-first GraphQL
-
Data API
mutation dropTableBook {
dropTable(
keyspaceName:"library",
tableName:"article"
)
}
Remove the table’s type
definition from the GraphQL schema, and then redeploy the schema.
The keyspace is specified in the endpoint path.
"dropTable": {
"name": "article"
}
-
CQL-first GraphQL
-
Schema-first GraphQL
-
Data API
mutation createIndexBook {
createIndex(
keyspaceName:"library",
tableName:"book",
columnName:"author",
indexName:"author_idx"
)
}
In a type
definition, the @cql_index
directive creates indexes for non-primary key columns:
author: String @cql_index(name: "author_idx")
The keyspace and table are specified in the endpoint path.
"createIndex": {
"name": "author_idx",
"definition": {
"column": "author"
}
}
Data operations
This section compares how you read and write table data with the Data API and the GraphQL API.
- The Data API doesn’t require you to pre-define your queries
-
Because the Data API has no API-specific schema, you don’t need to pre-define query or mutation operations. Instead, you use a set of standard insert, find, update, and delete commands that offer various parameters to configure the target and outcome of each request.
- Make sure your reads and writes are compliant with the Data API
-
Make sure your read and write operations follow the expected syntax and supported CQL functionality for the Data API:
-
Migrate to the Data API from CQL: Learn about unsupported CQL types and operations, as well as compatibility for existing CQL tables that contain unsupported types. If your existing data contains unsupported or custom types, you might need to migrate that data to new columns of supported types. Similarly, your application code might need to be modified to accept supported types.
-
Data types in tables: Learn the read and write format for different data types.
-
- The Data API doesn’t support
consistency
,serialConsistency
, orttl
-
The Data API doesn’t provide equivalents to the GraphQL API’s
consistency
,serialConsistency
, orttl
options.If your tables contain TTLs or static values, see Support for existing tables.
- Updates and inserts are upserts
-
Any CQL
INSERT
orUPDATE
operation is also an upsert:-
An
INSERT
with the same primary key as an existing row overwrites the existing row with the given values. -
An
UPDATE
applied to a non-existent row creates a new row with the given values, unless theUPDATE
only unsets values.
-
- Query operators are similar but not identical
-
Like the GraphQL API, the Data API uses query operators to find data. Both APIs support flexible filtering with similar, but not identical, query operators (predicates).
For read operations, the Data API provides query operators that align with all of the GraphQL API query predicates except
contains
,containsKey
, andcontainsEntry
.For update and delete operations, Data API restricts the filter operators and columns. For example, the command to delete one row is limited to the primary key columns and the
$eq
operator so that you can specify the unique row to delete.For more information and examples, see Filter operators for tables.
- Use projections to return specific columns
-
The Data API uses projections to specify the columns returned by any operation that returns full rows by default. For more information, see Projections for tables.
Additionally, some Data API commands return short responses by default or offer other options to manipulate the response content. These behaviors and options are described in the reference documentation for applicable commands.
- The Data API supports vector search, sorting, skipping, and response limits
-
The Data API provides
sort
,skip
, andlimit
options for read requests.You can use sort clauses for ascending/descending sorting and similarity search. For more information, see Sort clauses for tables.
For information about
skip
andlimit
, see Find rows: Parameters. - Pagination still applies
-
Both the GraphQL API and the Data API can apply pagination to responses. Page size and availability of pagination depend on the type of request. For more information, see Find rows: Result and Find rows: Iterate over found rows.
Data command compatibility matrix
The following table maps GraphQL API data operations to their equivalent Data API commands.
This table is based on HTTP endpoints. If you use a client, your scripts must include additional commands as needed to work with certain endpoints. For example, row-level operations require a Table object.
Operation | GraphQL API operation | Data API reference |
---|---|---|
Insert rows |
|
|
Read rows |
|
|
Read specific columns |
With a query, specify columns to return or define a payload type (schema-first only) |
|
Update (or upsert) a row |
|
|
Delete rows |
|
Data code examples
The following code samples compare some GraphQL API data operations with the equivalent Data API commands over HTTP. For more information and equivalencies for all GraphQL API data operations, see Data command compatibility matrix.
-
CQL-first GraphQL
-
Schema-first GraphQL
-
Data API
mutation insert2Books {
moby: insertbook(value: {title:"Moby Dick", author:"Herman Melville"}) {
value {
title
}
}
catch22: insertbook(value: {title:"Catch-22", author:"Joseph Heller"}) {
value {
title
}
}
}
Assuming the table and mutation are defined in the GraphQL schema:
mutation insert2books {
nativeson: insertBook(book: { title: "Native Son", isbn: "978-0061148507", author: ["Richard Wright"] }) {
title
}
mobydick: insertBook(book: { title: "Moby Dick", isbn: "978-1503280786", author: ["Herman Melville"]}) {
title
}
}
The keyspace and table are specified in the endpoint path.
"insertMany": {
"documents": [
{
"title": "Computed Wilderness",
"author" :"Ryan Eau",
"number_of_pages": 432,
"genres": ["History", "Biography"]
},
{
"title": "Moby Dick",
"author" :"Herman Melville",
"number_of_pages": 745,
"genres": ["Classic", "Epic", "Nautical"]
}
]
}
-
CQL-first GraphQL
-
Schema-first GraphQL
-
Data API
query threeBooks {
book(filter: { title: { in: ["Native Son", "Moby Dick", "Catch-22"] } } ) {
values {
title
author
}
}
}
Assuming the query is defined in the GraphQL schema:
query fetchBook {
book(title: "Native Son") {
title
author
}
}
The keyspace and table are specified in the endpoint path.
{
"find": {
"filter": {
"author": { "$in": [ "Sara Jones", "Jennifer Ray" ] }
},
"projection": {
"title": true,
"genres": true
}
}
}
-
CQL-first GraphQL
-
Schema-first GraphQL
-
Data API
mutation updateOneBook {
moby: updatebook(value: {title:"Moby Dick", author:"Herman Melville", isbn: "9780140861723"} ) {
value {
title
author
isbn
}
}
}
Assuming the mutation is defined in the GraphQL schema:
mutation updateOneBook {
updateBook(book: {
title: "Moby Dick",
author: ["Herman Melville", "Some Translator"],
language: "Spanish",
isbn: "9780140861723" })
}
The keyspace and table are specified in the endpoint path.
{
"updateOne": {
"filter": {
"title": "Moby Dick",
"author": "Herman Melville"
},
"update": {
"$set": {
"isbn": "9780140861723"
}
}
}
}
-
CQL-first GraphQL
-
Schema-first GraphQL
-
Data API
mutation deleteOneBook {
prideAndPrejudice: deletebook(value: {title:"Pride and Prejudice", author: "Jane Austen"}, ifExists: true ) {
value {
title
}
}
}
Assuming the mutation is defined in the GraphQL schema:
mutation deleteOneBook {
deleteBook(book: { title:"Pride and Prejudice"})
}
The keyspace and table are specified in the endpoint path.
"deleteOne": {
"filter": {
"title": "Hidden Shadows of the Past",
"author": "John Anthony"
}
}
Migrate from the Stargate gRPC API
If you use the Stargate gRPC API, DataStax recommends that you migrate your code to a Cassandra driver.
This is because the Stargate gRPC API and the Cassandra drivers both use string-quoted CQL statements in application code. This can reduce the level of effort required for the migration because you can preserve the CQL statements in your application code.
In contrast, a greater level of effort is required to migrate from the gRPC API to the Data API:
-
You must convert your CQL statements to Data API commands in addition to transforming the rest of your application code.
-
Your data must be stored in a Serverless (Vector) database because the Data API isn’t available to Serverless (Non-Vector) databases.
-
Your application can’t use CQL functionality that isn’t supported by the Data API.