GraphQL sur une base clé-valeur, on dirait presque une provocation. D’un côté, le modèle de données le plus dépouillé qui soit : une clé, une valeur, point. De l’autre, le langage de requête typé qu’on réserve d’ordinaire aux API exposant des graphes d’objets assez profonds. Les deux mondes n’avaient a priori pas grand-chose à se dire.
Et pourtant, c’est exactement ce que Materia KV vous propose désormais : vous continuez à écrire vos données avec n’importe quel client Redis ou Valkey, et vous pouvez les relire via un endpoint GraphQL. Pas de couche de synchronisation, pas de réplica à tenir à jour, pas de second stockage à alimenter. Tout ce que vous poussez d’un côté est interrogeable de l’autre dans la foulée, sur le même cluster. C’est la même base, vue par deux portes différentes.
Materia suit son chemin
Avant d’aller plus loin, rappelons d’où vient Materia KV, car le produit ne s’est pas construit en un jour. Depuis son entrée en Alpha publique, la base clé-valeur serverless de Clever Cloud s’est étoffée posément, au rythme de vos retours. Le TTL est rapidement arrivé pour gérer l’expiration des clés ; dans la foulée, le KV Explorer s’est invité dans la Console et la commande clever kv dans les Clever Tools, afin de consulter vos données sans installer le moindre outil tiers.
Sont ensuite venus les commandes JSON (JSON.GET, JSON.SET, JSON.DEL), puis le passage en bêta avec le support des Hash, le type Set au début de l’année, et tout récemment un lot de nouvelles commandes hash, string et TTL. Sans oublier qu’un tel add-on se déploie aussi bien via le provider Terraform que via le Clever Kubernetes Operator.
Le fil rouge de toute cette histoire reste le même : la compatibilité. Nous n’avons jamais voulu vous imposer une API maison, un ORM exotique ou un client estampillé Clever Cloud. Vous parlez à Materia KV avec des protocoles que vous connaissez déjà. La couche Redis/Valkey était la première. La couche GraphQL apporte une nouvelle dimension.
Comment ça marche en pratique ?
Vous écrivez via l’API Redis, vous lisez via GraphQL, et les deux interfaces tapent dans le même keyspace avec le même token : celui qui sert de mot de passe à votre redis-cli (votre $KV_TOKEN, alias $REDIS_PASSWORD, basé sur Eclipse Biscuit) sert aussi de bearer token côté GraphQL. Vous n’avez donc rien à faire pour un add-on existant.
Materia KV étant un cluster distribué, l’endpoint est une URL unique, partagée par tous les add-ons : https://materiakv-graphql.eu-fr-1.services.clever-cloud.com/graphql.
Le schéma expose un seul type racine, MateriaKvQuery, qui couvre les strings, les hashs et les sets. Ouvrez l’URL dans un navigateur et vous tombez sur un playground GraphiQL où explorer tout le schéma, ou récupérez le SDL avec l’outil d’introspection de votre choix.
Une précision avant d’aller plus loin : pour l’instant, c’est de la lecture seule. Aucune mutation. Et c’est souvent suffisant en l’état : écrire reste l’affaire des clients Redis/Valkey, qui le font déjà parfaitement, pendant que GraphQL se concentre sur les requêtes de données.
Place à la pratique. Dans tout ce qui suit, on écrit avec redis-cli et on relit avec curl, en supposant les variables de l’add-on chargées dans l’environnement :
# 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"
Une string pour commencer. On pose une clé côté redis-cli, puis on la lit côté 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"}}'
Ce qui renvoie le résultat suivant :
{ "data": { "string": { "key": "demo:greeting", "value": "Hello, Materia!" } } }
Ce qui a été écrit d'un côté est lisible de l'autre, sans délai ni couche intermédiaire. Là où GraphQL prend l'avantage, c'est dès que vos données sont plus complexes. Un hash par exemple, transporte un enregistrement structuré :
redis-cli -h $KV_HOST -p $KV_PORT --tls \
HSET demo:user:alice name Alice role admin email alice@example.com active true
GraphQL peut vous le renvoyer sous la forme d'une liste typée de paires { name, value }, et vous n'avez plus à découper une réponse plate à la main côté client :
query ReadUser($key: String!) {
hash(key: $key) {
key
fields { name value }
}
}
La même logique s'applique pour un set, cette collection sans ordre ni doublon que les deux protocoles exposent comme un objet de première classe :
redis-cli -h $KV_HOST -p $KV_PORT --tls SADD demo:group:admins alice bob carol
Pourra être interrogé avec la requête suivante :
query ReadGroup($key: String!) {
getSetMembers(key: $key) { key members }
}
Requêtes complexes : là où GraphQL brille
Mais voici le morceau qui justifie à lui seul l'existence de cette couche de compatibilité : GraphQL n'expose pas seulement vos sets, il sait les combiner : trouver les membres présents dans deux groupes à la fois tient en une requête, sans recourir à SINTER, sans index pré-calculé, sans fusion côté client.
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
Avec keys = ["demo:group:admins", "demo:group:active"], vous récupérez ["alice", "carol"]. Les champs setUnion et setDifference répondent au même schéma : qui est admin et actif, qui est l'un ou l'autre, qui est admin mais pas actif. Le calcul reste sur le cluster, vous ne rapatriez que le résultat :
query AdminsAndActive($keys: [String!]!) {
setIntersection(keys: $keys)
}
Le TTL, vu sous deux angles
Un détail pour celles et ceux qui apprécient les formats bien choisis. Redis raisonne en TTL relatif, en secondes ; GraphQL, lui, vous renvoie l'instant d'expiration absolu via le champ expireAt, typé avec un scalaire DateTime (RFC 3339). Deux représentations de la même vérité, chacune dans l'unité qui a du sens pour son protocole.
redis-cli -h $KV_HOST -p $KV_PORT --tls SET demo:session:xyz auth-token-42 EX 300
La requête GraphQL sera alors :
query ReadSession($key: String!) {
string(key: $key) { key value expireAt }
}
Quant aux documents JSON, Materia KV les stocke par-dessus les strings tout en gardant l'API JSON de Redis. GraphQL vous rend le document sérialisé tel quel : vous le parsez côté client, et chaque champ fait l'aller-retour sans perte.
Testez de bout en bout
Pour voir les deux couches fonctionner de concert, nous avons publié une démo interactive, déployable sur Clever Cloud, dont le code source est disponible sur GitHub.
Écrite avec Bun et ses API natives (Bun.serve, Bun.RedisClient), sans framework ni librairie superflue, elle déroule six scénarios — string, hash, set, intersection, TTL, JSON. Vous cliquez, elle vous montre côte à côte les commandes Redis envoyées et la requête GraphQL qui relit le résultat, avec les variables, les réponses brutes et les temps de réponse.
La déployer tient en quelques commandes :
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
Et après ?
Cette première implémentation de GraphQL nous permet de vous faire tester cette approche, de récolter vos avis. Ce n'est pas une fin en soi : les mutations font partie des pistes sur la table, et comme d'habitude avec Materia KV, ce sont vos usages qui décideront de l'ordre des priorités. N'hésitez donc pas à l'éprouver et à nous signaler ce qui vous manque.
Pour creuser, tout est là : la documentation de la couche GraphQL, l'annonce au changelog, et l'exemple complet. Et pour ceux qui attendent de pouvoir profiter de la résilience de Materia avec des clients issus de l'écosystème DynamoDB, c'est en cours via un produit dédié. Il est actuellement en test auprès de clients qui l'utilisent pour des besoins spécifiques et sera ouvert plus largement un peu plus tard dans l'année.