GraphQL API

Overview

The Stargate GraphQL API is implemented to easily modify and query your table data using GraphQL types, mutations, and queries with any Cassandra deployment.

The Stargate GraphQL API has two modes, one developed from native GraphQL schema principles, and one developed with the Cassandra Query Language (CQL) in mind. To distinguish these two modes, the rest of the documentation will refer to the modes as schema-first and cql-first.

The CQL-first approach directly translates CQL tables into GraphQL types, mutations, and queries. The GraphQL schema is automatically generated from the keyspace, tables, and columns defined, but no customization is allowed. A standard set of mutations and queries are produced for searching and modifying the table data. If you are familiar with Cassandra, you might prefer this approach.

The schema-first approach allows you to create idiomatic GraphQL types, mutations, and queries in a manner familiar to GraphQL developers. The schema is deployed and can be updated by deploying a new schema without recreating the tables and columns directly. Under the covers, this approach will create and modify the CQL tables to match the GraphQL types. The schema can be modified for CQL decorated schema, such as specifying table and column names in Cassandra, while retaining GraphQL-centric names for the types that correspond. If you are a GraphQL developer, this approach is for you.

To compare the two approaches, let’s look at an example that creates a container (table or type) to hold information about a reader:

 cql-first
 reader: createTable(
  keyspaceName:"library",
  tableName:"reader",
  partitionKeys: [ { name: "name", type: {basic: TEXT} } ]
  # Secondary key used to access values within the partition
  clusteringKeys: [ { name: "user_id", type: {basic: UUID}, order: "ASC" } ]
  values: [
    { name: "birthdate", type: {basic: DATE} }
    { name: "email", type: {basic: SET, info:{ subTypes: [ { basic: TEXT } ] } } }
    { name: "reviews", type: {basic: TUPLE,
      info: { subTypes: [ { basic: TEXT }, { basic: INT }, { basic: DATE } ] } } }
    { name: "addresses", type: { basic: LIST,
      info: { subTypes: [ { basic: UDT, info: { name: "address_type", frozen: true } } ] } } }
    ]
  )
}
 schema-first
 type Reader @key @cql_entity(name: "reader") @cql_input {
  name: String! @cql_column(partitionKey: true)
  user_id: Uuid! @cql_column(clusteringOrder: ASC)
  birthdate: Date @cql_index(name: "date_idx")
  email: [String] @cql_column(typeHint: "set<varchar>")
  reviews: [Review] @cql_index(name: "review_idx", target: VALUES)
  address: [Address]
}

The two approaches are similar, in that both must name the columns (cql-first) or fields (schema-first). The data type must be specified for each column or field. Although the syntax of the data type is different, by comparing, you can see that they are similar. Each approach can define the primary key composed of one or more partition keys and zero or more clustering keys. The column reviews in the cql-first example is defined as a tuple, but since the schema-first approach doesn’t support tuples, a user-defined type Review is used instead. The UDTs are not included here for brevity, but are explained later.

The main difference in the two approaches shown here are the CQL directives included in the schema-first type. To extend the power of Cassandra, these directives allow a user to fine-tune, if you choose, how the type is defined in the underlying database.

The other difference, not illustrated here, is that, in the cql-first approach, mutations and queries are automatically generated, but no customization is possible. In the schema-first approach, the developer is responsible for declaring the mutations and queries, and so has the freedom to do whatever is needed for an application.

For more information about the GraphQL API, see the blog post on the GraphQL API.

You can start with a GraphQL QuickStart or follow the full instructions: (schema-first) (cql-first) .

We’ll show you you how to:

  1. Generate an authorization token

  2. Create a keyspace (schema-first) (cql-first)

  3. Delete a keyspace (schema-first) (cql-first)

  4. Optional Create a user-defined type (UDT) (schema-first) (cql-first)

  5. Optional Delete a UDT (cql-first)

  6. Create object types (schema-first)

  7. Create table schema (cql-first)

  8. Delete table schema (cql-first)

  9. Optional Create indexes (schema-first) (cql-first)

  10. Deploy schema (schema-first)

  11. Undeploy schema (schema-first)

  12. Add data (schema-first) (cql-first)

  13. Get data (schema-first) (cql-first)

  14. Update data (schema-first) (cql-first)

  15. Delete data (schema-first) (cql-first)

About the GraphQL API endpoints

There are three Stargate GraphQL API endpoints, one for creating schema in cql-first, one for deploying schema in the graphql-first, and the third for querying or mutating a keyspace. The URLS are:

The schema endpoint is used to create or alter CQL schema in the cql-first GraphQL using direct schema manipulation. The admin endpoint is used to deploy GraphQL schema in the graphql-first GraphQL which will indirectly modify underlying CQL schema. The querying endpoint is constructed in the same manner for both graphql-first and cql-first.

Each request must have a valid application token. Each request can also have an optional unique request id. The request id is recommended in a production environment and can be useful in troubleshooting issues.

Generating UUIDs Consider using a tool like this online UUID generator to quickly create a random UUID to pass with your requests if you are submitting the queries manually using a tool like cURL.

Naming conventions for GraphQL

The GraphQL API uses specific naming conventions to preserve capitalization and special characters. Note that if typical GraphQL naming conventions are used, such as camelCase, that the underlying Cassandra storage tables will use double quoting to preserve the capitalization. If a naming conflict occurs, an error results that the table already exists.

Table 1. GraphQL naming convention
GraphQL table name CQL table name GraphQL mutation format

foo

foo

insertfoo

Foo

"Foo"

insertFoo

foo_bar

foo_bar

insertfoo_bar

FooBar

"FooBar"

insertFooBar

Hellox21_

"Hello!"

insertHellox21_

Using the GraphQL Playground

The easiest way to get started with GraphQL uses the built-in GraphQL playground. In Astra, go to the Connect tab for your database, choose GraphQL under the Connect using an API and you’ll see instructions for accessing the playground. The GraphQL playground launches the url https://localhost:8080/playground in your browser.

Add your application token to the HTTP HEADERS section at the lower lefthand corner of the GraphQL Playground window:

{"x-cassandra-token":"$AUTH_TOKEN"}

Once in the playground, you can create new schema and interact with the GraphQL APIs. The server paths are structured to provide access to creating and querying schema, as well as querying and modifying Cassandra data:

  • /graphql-schema

    • An API for exploring and creating schema, or Data Definition Language (DDL). For example, Astra has queries to create, modify, or drop tables, such as createTable, or dropTable.

  • /graphql-admin

    • An API for deploying GraphQL schema.

  • /graphql/<keyspace>

    • An API for querying and modifying data in your tables using GraphQL fields.

Using Postman

If you prefer, you can use Postman as a client interface for exploring the GraphQL API (download here). We’ve provided a Stargate GraphQL API Postman Astra Collection that you can import in Postman to play with the examples shown in this walkthrough.