Store KV
KV est un store clé/valeur durable, limité à votre application. C'est un store de chaînes :
chaque valeur est enregistrée sous forme de chaîne. Clés et valeurs appartiennent à votre
application seule (voir le client createSdk dans la Présentation du SDK).
API
import { createSdk } from "@bext-stack/framework/sdk";
const sdk = createSdk("<app-id>");
await sdk.kv.set("greeting", { hello: "world" }, 3600); // optional TTL in seconds
const value = await sdk.kv.get<{ hello: string }>("greeting");
await sdk.kv.delete("greeting");
const keys = await sdk.kv.list("post:", 100); // prefix + limit
| Méthode | Description |
|---|---|
get<T>(key) |
Lire et décoder une valeur. Retourne null si la clé n'existe pas ou a expiré. |
set(key, value, ttlSecs?) |
Écrire une valeur (création ou remplacement), avec expiration optionnelle après ttlSecs secondes. |
delete(key) |
Supprimer une clé. Retourne true si elle existait. |
list(prefix?, limit?) |
Lister les noms de clés, éventuellement filtrés par préfixe. limit vaut 100 par défaut. |
En cas d'échec, chaque méthode lève une Error qui porte le message renvoyé par le serveur
(ou le statut HTTP à défaut). Une clé absente n'est pas une erreur : get retourne null.
Les lectures KV faites pendant le rendu sont servies directement par le runtime : lire du KV depuis un loader ou un composant reste rapide.
Sémantique
- Store de chaînes : les valeurs sont stockées sous forme de chaînes.
- TTL : passez
ttlSecs(un nombre entier de secondes) àkv.setpour qu'une clé expire. Une valeur décimale ou négative est ignorée et la clé n'expire pas. Une clé expirée n'est plus retournée pargetni parlist. - Chaque
setremplace tout : la valeur et l'expiration. UnsetsansttlSecssur une clé qui en avait une la rend permanente ; repassez le TTL à chaque écriture si vous voulez le garder. Il n'y a pas de fusion : deux écritures concurrentes sur la même clé, la dernière l'emporte. - Listing par préfixe :
listaccepte unprefixet unelimit, et ne retourne que les noms de clés, dans un ordre non garanti. Dans le préfixe,_et%se comportent comme des jokers (un caractère quelconque, une suite quelconque) et la comparaison ignore la casse des lettres ASCII :list("user_")peut donc aussi retourneruserX…ouUSER_…. Filtrez le résultat aveckey.startsWith(prefix)si la correspondance exacte compte.
Le piège du double encodage
Le client sérialise en JSON (JSON.stringify) la valeur passée à set, et le serveur stocke
cette chaîne encodée une fois de plus en JSON : la valeur stockée est enveloppée deux fois. À la
lecture, le client applique JSON.parse, jusqu'à trois fois, tant que le résultat est encore une
chaîne.
En pratique :
- Les objets, tableaux, nombres et booléens font l'aller-retour par
sdk.kvsans changement. - Une chaîne qui est elle-même du JSON valide ne le fait pas :
set("k", "42")se relit comme le nombre42, etset("k", '{"a":1}')comme un objet. Enveloppez ces chaînes dans un objet ({ value: "42" }) quand la chaîne exacte compte. - Si vous lisez la valeur stockée brute par un autre moyen, attendez-vous à un double encodage JSON.
Motif : enregistrement de job durable en KV
La Queue ne stocke pas de résultat et n'a pas de statut par message. Pour suivre l'issue d'un job, ajoutez un enregistrement de job durable en KV :
// Store a record when you enqueue…
await sdk.kv.set(`job:${id}`, { status: "queued", submittedAt: Date.now() });
// …the worker updates it as it progresses…
await sdk.kv.set(`job:${id}`, { status: "running" });
// …and on completion or failure.
await sdk.kv.set(`job:${id}`, { status: "complete", result });
Chaque set écrase l'enregistrement entier : dans cet exemple, submittedAt disparaît au
deuxième appel. Relisez avec get puis réécrivez l'objet complet si vous voulez conserver des champs.
Utilisez des clés comme job:<id> et quelques petites fonctions submit / get / complete / fail
autour. Voir Queue pour la mise en file, ou Tasks & Planificateur, dont
les tasks suivent déjà le statut pour vous.
Et ensuite
| Page | Ce qu'elle couvre |
|---|---|
| Cache | Mise en cache à TTL et différence avec KV |
| Queue | Jobs sans retour de résultat, le motif d'enregistrement de job |
| Tasks & Planificateur | Traitements longs avec statut et progression intégrés |
| Présentation du SDK | Le client createSdk et l'interface BextSdk |