Materia KV now speaks GraphQL

Materia KV GraphQL EN
You write to Materia KV using a Redis or Valkey client, then access your data through a typed GraphQL endpoint. Same cluster, same token, no synchronization layer in between. Use the best of both worlds depending on your needs. Here’s how it works.

GraphQL on a key-value database almost sounds like a provocation. On one side, the simplest data model imaginable: a key, a value, and that’s it. On the other, a typed query language usually associated with APIs exposing fairly deep object graphs. At first glance, these two worlds did not seem to have much to say to one another.

And yet, this is exactly what Materia KV now offers. You can continue writing data with any Redis or Valkey client and read it back through a GraphQL endpoint. No synchronization layer, no replica to maintain, no secondary datastore to feed. Everything you write on one side becomes immediately queryable on the other, within the same cluster. It’s the same database, seen through two different doors.

Materia keeps finding its way

Before going any further, let’s briefly revisit where Materia KV comes from, because the product was not built overnight. Since entering public Alpha, Clever Cloud’s serverless key-value database has steadily evolved based on your feedback. TTL support was quickly added to handle key expiration ; shortly afterward, KV Explorer was added to the Console, along with the clever kv command in Clever Tools, allowing you to browse your data without installing any third-party software.

JSON commands (JSON.GET, JSON.SET, JSON.DEL) came next, followed by the move to Beta with Hash support, the Set type earlier this year, and more recently a batch of new hash, string, and TTL commands. And let’s not forget that such an add-on can be deployed through both the provider Terraform and the Clever Kubernetes Operator.

The common thread running through this whole story remains the same: compatibility. We never wanted to force you into a proprietary API, an exotic ORM, or a Clever Cloud-branded client. You interact with Materia KV using protocols you already know. Redis/Valkey support came first. The GraphQL layer brings a new dimension.

How does it work in practice?

You write through the Redis API, read through GraphQL, and both interfaces operate on the same keyspace using the same token. The password used by your redis-cli ($KV_TOKEN, also available as $REDIS_PASSWORD, based on Eclipse Biscuit) also serves as the GraphQL bearer token. Existing add-ons therefore require no changes.

Because Materia KV is a distributed cluster, the endpoint is a single URL shared by all add-ons: https://materiakv-graphql.eu-fr-1.services.clever-cloud.com/graphql.

The schema exposes a single root type, MateriaKvQuery, covering strings, hashes, and sets. Open the URL in your browser and you’ll find a GraphiQL playground where you can explore the entire schema, or retrieve the SDL using the introspection tool of your choice.

One detail before we go any further: for now, this is read-only. No mutations. In many cases, that is sufficient. Writing remains the job of Redis and Valkey clients, which already do it perfectly well, while GraphQL focuses on querying data.

Time for some hands-on examples. Throughout the following examples, we write using redis-cli and read using curl, assuming the add-on environment variables have been loaded:

# On récupère les variables d'environnement de l'add-on, vous pouvez aussi le faire via un fichier .env par exemple
source <(clever addon env ADDON_ID -F shell)
export KV_GRAPHQL_URL="https://materiakv-graphql.eu-fr-1.services.clever-cloud.com/graphql"

First, a string. We create a key with redis-cli, then read it back through GraphQL:

redis-cli -h $KV_HOST -p $KV_PORT --tls SET demo:greeting "Hello, Materia!"

curl -s "$KV_GRAPHQL_URL" \
  -H "Authorization: Bearer $KV_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query":"query($key:String!){ string(key:$key){ key value } }","variables":{"key":"demo:greeting"}}'

Which returns:

{ "data": { "string": { "key": "demo:greeting", "value": "Hello, Materia!" } } }

What was written on one side is immediately readable on the other, with no delay and no intermediary layer. Where GraphQL starts to pull ahead, is when your data becomes more complex. Take a hash, for example, which carries a structured record:

redis-cli -h $KV_HOST -p $KV_PORT --tls \
 HSET demo:user:alice name Alice role admin email alice@example.com active true

GraphQL can return it as a typed list of { name, value } pairs, eliminating the need to manually parse a flat response on the client side:

query ReadUser($key: String!) {
  hash(key: $key) {
    key
    fields { name value }
  }
}

The same logic applies to a set, that collection of unique, unordered values that both protocols expose as a first-class object:

redis-cli -h $KV_HOST -p $KV_PORT --tls SADD demo:group:admins alice bob carol

It can then be queried using:

query ReadGroup($key: String!) {
  getSetMembers(key: $key) { key members }
}

Complex queries: where GraphQL shines

But here’s the part that, on its own, justifies the existence of this compatibility layer: GraphQL doesn’t just expose your sets, it knows how to combine them. Finding members present in two groups at the same time becomes a single query, without using SINTER, without precomputed indexes, and without performing the merge client-side.

redis-cli -h $KV_HOST -p $KV_PORT --tls SADD demo:group:admins alice bob carol
redis-cli -h $KV_HOST -p $KV_PORT --tls SADD demo:group:active alice carol dave

With keys = ["demo:group:admins", "demo:group:active"], you obtain: ["alice", "carol"]. The setUnion and setDifference fields follow the same principle: who is both admin and active, who is either one, who is an admin but not active. The computation remains on the cluster; only the result is returned:

query AdminsAndActive($keys: [String!]!) {
  setIntersection(keys: $keys)
}

TTL, seen from two angles

A detail for those who appreciate well-chosen formats. Redis thinks in relative TTLs, expressed in seconds; GraphQL, on the other hand, returns the absolute expiration timestamp through the expireAt field, typed as a DateTime scalar (RFC 3339). Two representations of the same truth, each in the unit that makes sense for its protocol.

redis-cli -h $KV_HOST -p $KV_PORT --tls SET demo:session:xyz auth-token-42 EX 300

The GraphQL query will then be:

query ReadSession($key: String!) {
  string(key: $key) { key value expireAt }
}

As for JSON documents, Materia KV stores them on top of strings while keeping Redis’ JSON API. GraphQL returns the serialized document as is: you parse it client-side, and every field makes the round trip without loss.

Test it end to end

To see the two layers working in concert, we have published an interactive demo, deployable on Clever Cloud, with the source code available on GitHub.

Written with Bun and its native APIs (Bun.serve, Bun.RedisClient), without any framework or superfluous library, it walks through six scenarios — string, hash, set, intersection, TTL, JSON. You click, and it shows you side by side the Redis commands being sent and the GraphQL query that reads the result back, with variables, raw responses, and response times.

Deploying it takes just a few commands:

git clone https://github.com/CleverCloud/kv-graphql-example
cd kv-graphql-example

clever create -t node -a kv-graphql-example
clever addon create kv kv-graphql-example --link kv-graphql-example 
clever env set KV_GRAPHQL_URL "https://materiakv-graphql.eu-fr-1.services.clever-cloud.com/graphql"

clever deploy
clever open

What’s next?

This first GraphQL implementation lets you test this approach and share your feedback with us. It is not an end in itself: mutations are among the options on the table, and as usual with Materia KV, your use cases will decide the order of priorities. So feel free to put it through its paces and tell us what you think is missing.

To dig deeper, everything is there: the GraphQL layer documentation, the changelog announcement, and the full example. And for those waiting to benefit from Materia’s resilience with clients from the DynamoDB ecosystem, this is underway through a dedicated product. It is currently being tested by customers using it for specific needs and will be opened more broadly a little later this year.

Blog

À lire également

Materia KV now speaks GraphQL

You write to Materia KV using a Redis or Valkey client, then access your data through a typed GraphQL endpoint. Same cluster, same token, no synchronization layer in between. Use the best of both worlds depending on your needs. Here’s how it works.
Company Features

UP Program: Clever Cloud announces its fifth startup selection

With this new batch, Clever Cloud welcomes four startups to the UP Program: Sentibee, Pictaderm, Legaia and Cockpit Agriculture.
Company

Sōzu 2.0 — turning a reverse proxy into a programmable edge

Sōzu is the reverse proxy that sits in front of every application running on Clever Cloud. After eighteen months of work — first the HTTP/2 multiplexer, built on our existing kawa pivot, then almost every other layer of the proxy, and finally a long run in production on the cleverapps.io load balancers — Sōzu 2.0 is out.
Engineering