← Cloudflare Workers KV / kv / příklady
Vytvoření distribuovaného konfiguračního úložiště
Ukládání konfiguračních dat aplikace je pro Workers KV ideálním případem použití. Konfigurační data mohou zahrnovat údaje pro personalizaci aplikace pro jednotlivé uživatele nebo tenanty, aktivaci funkcí pro skupiny uživatelů, omezení přístupu pomocí seznamů povolených nebo zakázaných adres a podobně. Tyto případy použití mohou mít vysoký objem čtení, který Workers KV dobře cachuje, což zajišťuje nízkou latenci čtení z vaší aplikace Workers.
V tomto příkladu se konfigurační data aplikace používají k personalizaci aplikace Workers pro každého uživatele. Konfigurační data jsou uložena v externí aplikaci a databázi a do Workers KV se zapisují prostřednictvím REST API.
Zápis konfigurace z externí aplikace do Workers KV
V některých případech se hlavní zdroj pravdy pro konfigurační data může nacházet jinde než ve Workers KV. V takovém případě použijte REST API Workers KV k zápisu konfiguračních dat do vašeho jmenného prostoru Workers KV.
Následující externí aplikace Node.js ukazuje jednoduchý skript, který načte uživatelská data z databáze a zapíše je do Workers KV pomocí knihovny REST API.
const postgres = require('postgres');
const { Cloudflare } = require('cloudflare');
const { backOff } = require('exponential-backoff');
if(!process.env.DATABASE_CONNECTION_STRING || !process.env.CLOUDFLARE_EMAIL || !process.env.CLOUDFLARE_API_KEY || !process.env.CLOUDFLARE_WORKERS_KV_NAMESPACE_ID || !process.env.CLOUDFLARE_ACCOUNT_ID) {
console.error('Missing required environment variables.');
process.exit(1);
}
// Setup Postgres connection
const sql = postgres(process.env.DATABASE_CONNECTION_STRING);
// Setup Cloudflare REST API client
const client = new Cloudflare({
apiEmail: process.env.CLOUDFLARE_EMAIL,
apiKey: process.env.CLOUDFLARE_API_KEY,
});
// Function to sync Postgres data to Workers KV
async function syncPreviewStatus() {
console.log('Starting sync of user preview status...');
try {
// Get all users and their preview status
const users = await sql`SELECT id, preview_features_enabled FROM users`;
console.log(users);
// Create the bulk update body
const bulkUpdateBody = users.map(user => ({
key: user.id,
value: JSON.stringify({
preview_features_enabled: user.preview_features_enabled
})
}));
const response = await backOff(async () => {
console.log("trying to update")
try{
const response = await client.kv.namespaces.bulkUpdate(process.env.CLOUDFLARE_WORKERS_KV_NAMESPACE_ID, {
account_id: process.env.CLOUDFLARE_ACCOUNT_ID,
body: bulkUpdateBody
});
}
catch(e){
// Implement your error handling and logging here
console.log(e);
throw e; // Rethrow the error to retry
}
});
console.log(`Sync complete. Updated ${users.length} users.`);
} catch (error) {
console.error('Error syncing preview status:', error);
}
}
// Run the sync function
syncPreviewStatus()
.catch(console.error)
.finally(() => process.exit(0));DATABASE_CONNECTION_STRING = <DB_CONNECTION_STRING_HERE>
CLOUDFLARE_EMAIL = <CLOUDFLARE_EMAIL_HERE>
CLOUDFLARE_API_KEY = <CLOUDFLARE_API_KEY_HERE>
CLOUDFLARE_ACCOUNT_ID = <CLOUDFLARE_ACCOUNT_ID_HERE>
CLOUDFLARE_WORKERS_KV_NAMESPACE_ID = <CLOUDFLARE_WORKERS_KV_NAMESPACE_ID_HERE>-- Create users table with preview_features_enabled flag
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
username VARCHAR(100) NOT NULL,
email VARCHAR(255) NOT NULL,
preview_features_enabled BOOLEAN DEFAULT false
);
-- Insert sample users
INSERT INTO users (username, email, preview_features_enabled) VALUES
('alice', '[email protected]', true),
('bob', '[email protected]', false),
('charlie', '[email protected]', true);V této ukázce kódu aplikace Node.js čte uživatelská data z databáze Postgres a pomocí knihovny Cloudflare REST API pro Node.js je zapisuje do Workers KV, kde slouží jako konfigurace pro naši aplikaci Workers. Aplikace navíc při opakování požadavků po chybě používá exponenciální prodlevu.
Použití konfiguračních dat z Workers KV ve vaší aplikaci Worker
Jakmile jsou konfigurační data uložena v oboru názvů Workers KV, můžeme je v naší aplikaci Workers použít k personalizaci aplikace pro každého uživatele.
// Example configuration data stored in Workers KV:
// Key: "user-id-abc" | Value: {"preview_features_enabled": false}
// Key: "user-id-def" | Value: {"preview_features_enabled": true}
interface Env {
USER_CONFIGURATION: KVNamespace;
}
export default {
async fetch(request, env) {
// Get user ID from query parameter
const url = new URL(request.url);
const userId = url.searchParams.get('userId');
if (!userId) {
return new Response('Please provide a userId query parameter', {
status: 400,
headers: { 'Content-Type': 'text/plain' }
});
}
const userConfiguration = await env.USER_CONFIGURATION.get<{
preview_features_enabled: boolean;
}>(userId, {type: "json"});
console.log(userConfiguration);
// Build HTML response
const html = `
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.preview-banner {
background-color: #ffeb3b;
padding: 10px;
text-align: center;
margin-bottom: 20px;
border-radius: 4px;
}
</style>
</head>
<body>
${userConfiguration?.preview_features_enabled ? `
<div class="preview-banner">
🎉 You have early access to preview features! 🎉
</div>
` : ''}
<h1>Welcome to My App</h1>
<p>This is the regular content everyone sees.</p>
</body>
</html>
`;
return new Response(html, {
headers: { "Content-Type": "text/html; charset=utf-8" }
});
}
} satisfies ExportedHandler<Env>;{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "<ENTER_WORKER_NAME>",
"main": "src/index.ts",
"compatibility_date": "2025-03-03",
"observability": {
"enabled": true
},
"kv_namespaces": [
{
"binding": "USER_CONFIGURATION",
"id": "<YOUR_BINDING_ID>"
}
]
}Tento kód použije cestu z adresy URL a najde soubor přiřazený k této cestě v úložišti KV. Zároveň nastaví v odpovědi správný typ MIME, aby prohlížeč věděl, jak s ní naložit. K načtení hodnoty z úložiště KV tento kód používá arrayBuffer ke správné práci s binárními daty, jako jsou obrázky, dokumenty a video či audio soubory.
Optimalizace výkonu pro konfiguraci
Chcete-li optimalizovat výkon, můžete hodnoty sloučit do menšího počtu párů klíč-hodnota. Díky tomu můžete dosáhnout vyšší efektivity ukládání do mezipaměti a nižší latence.
Místo ukládání konfigurace každého uživatele do samostatného páru klíč-hodnota můžete například uložit konfigurace všech uživatelů do jediného páru klíč-hodnota. Tento přístup se hodí pro případy, kdy jsou konfigurační data malá a dají se snadno spravovat v jediném páru klíč-hodnota (v rámci limit velikosti hodnoty Workers KV je 25 MiB).