String Operations
The DBX TypeScript SDK provides comprehensive string operations with full TypeScript support and high-performance NAPI bindings.
Installation
npm install @0dbx/redis
Basic Usage
import { DbxRedisClient } from "@0dbx/redis";
// Create client
const client = new DbxRedisClient("http://localhost:3000");
// String operations
await client.string.set("my-key", "hello world", 3600); // with TTL
const value = await client.string.get("my-key");
console.log(value); // "hello world"
WebSocket Client
import { DbxWsClient } from "@0dbx/redis";
// Create WebSocket client
const wsClient = new DbxWsClient("ws://localhost:3000/redis_ws");
// String operations via WebSocket
await wsClient.string.set("my-key", "hello world");
const value = await wsClient.string.get("my-key");
String Operations
The DBX TypeScript SDK provides comprehensive string operations for Redis. This guide covers all available string methods and their usage patterns.
Overview
String operations are the most basic data type in Redis, supporting simple key-value storage with additional features like expiration and existence checks.
Basic Operations
Creating a String Client
import { DbxRedisClient } from "@0dbx/redis";
const client = new DbxRedisClient("http://localhost:3000");
const stringClient = client.string;
Setting Values
// Set a simple string value
await stringClient.set("my-key", "hello world");
// Set with TTL (Time To Live) in seconds
await stringClient.set("my-key", "hello world", 3600); // expires in 1 hour
// Set with 0 TTL (no expiration)
await stringClient.set("my-key", "hello world", 0);
Getting Values
// Get a string value
const value = await stringClient.get("my-key");
console.log(value); // "hello world"
// Get a non-existent key
try {
const value = await stringClient.get("non-existent-key");
} catch (error) {
console.log("Key not found");
}
Deleting Values
// Delete a key
await stringClient.delete("my-key");
// Check if deletion was successful
try {
const value = await stringClient.get("my-key");
} catch (error) {
console.log("Key was successfully deleted");
}
Advanced Operations
Checking Existence
// Check if a key exists
const exists = await stringClient.exists("my-key");
console.log(exists); // true or false
TTL Operations
// Get remaining TTL for a key
const ttl = await stringClient.ttl("my-key");
console.log(ttl); // seconds remaining, -1 if no TTL, -2 if key doesn't exist
// Set TTL for an existing key
await stringClient.expire("my-key", 7200); // 2 hours
// Remove TTL (make key persistent)
await stringClient.expire("my-key", -1);
Batch Operations
// Perform multiple string operations in a single request
const results = await stringClient.batch([
{ type: "set", key: "key1", value: "value1", ttl: 3600 },
{ type: "set", key: "key2", value: "value2" },
{ type: "get", key: "key3" },
{ type: "delete", key: "key4" },
]);
console.log(results);
// [
// { success: true, key: "key1" },
// { success: true, key: "key2" },
// { value: "value3" },
// { success: true, deleted: true }
// ]
WebSocket String Operations
Creating a WebSocket String Client
import { DbxWsClient } from "@0dbx/redis";
const wsClient = new DbxWsClient("ws://localhost:3000/redis_ws");
const wsStringClient = wsClient.string;
WebSocket String Operations
// Set value via WebSocket
await wsStringClient.set("my-key", "hello world");
// Get value via WebSocket
const value = await wsStringClient.get("my-key");
// Delete value via WebSocket
await wsStringClient.delete("my-key");
// Check existence via WebSocket
const exists = await wsStringClient.exists("my-key");
// TTL operations via WebSocket
const ttl = await wsStringClient.ttl("my-key");
await wsStringClient.expire("my-key", 3600);
Error Handling
Common Error Patterns
try {
const value = await stringClient.get("non-existent-key");
} catch (error) {
if (error.message.includes("not found")) {
console.log("Key doesn't exist");
} else if (error.message.includes("timeout")) {
console.log("Request timed out");
} else {
console.error("Unexpected error:", error);
}
}
Type-Safe Error Handling
interface StringOperationError {
message: string;
code?: string;
status?: number;
}
async function safeStringOperation<T>(operation: () => Promise<T>): Promise<T | null> {
try {
return await operation();
} catch (error) {
const dbxError = error as StringOperationError;
switch (dbxError.code) {
case "not_found":
console.warn("Key not found");
return null;
case "timeout":
console.error("Operation timed out");
return null;
default:
console.error("String operation failed:", dbxError.message);
return null;
}
}
}
// Usage
const value = await safeStringOperation(() => stringClient.get("my-key"));
Performance Optimization
Connection Reuse
// Create a singleton client for your application
class StringService {
private static instance: DbxRedisClient;
private static stringClient: any;
static getInstance(): any {
if (!StringService.instance) {
StringService.instance = new DbxRedisClient("http://localhost:3000");
StringService.stringClient = StringService.instance.string;
}
return StringService.stringClient;
}
}
// Use throughout your application
const stringClient = StringService.getInstance();
Batch Operations for Performance
// Instead of multiple individual requests
const promises = [
stringClient.set("key1", "value1"),
stringClient.set("key2", "value2"),
stringClient.set("key3", "value3"),
];
await Promise.all(promises);
// Use batch operations for better performance
await stringClient.batch([
{ type: "set", key: "key1", value: "value1" },
{ type: "set", key: "key2", value: "value2" },
{ type: "set", key: "key3", value: "value3" },
]);
Caching Patterns
class CachedStringClient {
private cache = new Map<string, { value: string; expires: number }>();
private client: any;
constructor(client: any) {
this.client = client;
}
async get(key: string, ttl: number = 300): Promise<string | null> {
const cached = this.cache.get(key);
if (cached && cached.expires > Date.now()) {
return cached.value;
}
try {
const value = await this.client.get(key);
this.cache.set(key, {
value,
expires: Date.now() + ttl * 1000,
});
return value;
} catch (error) {
return null;
}
}
async set(key: string, value: string, ttl: number = 3600): Promise<void> {
await this.client.set(key, value, ttl);
this.cache.set(key, {
value,
expires: Date.now() + ttl * 1000,
});
}
}
// Usage
const cachedClient = new CachedStringClient(stringClient);
await cachedClient.set("my-key", "hello world", 3600);
const value = await cachedClient.get("my-key", 300); // 5-minute cache
Real-World Examples
User Session Management
class SessionManager {
private client: any;
private prefix = "session:";
constructor(client: any) {
this.client = client;
}
async createSession(userId: string, sessionData: any): Promise<string> {
const sessionId = this.generateSessionId();
const key = `${this.prefix}${sessionId}`;
await this.client.set(key, JSON.stringify(sessionData), 86400); // 24 hours
return sessionId;
}
async getSession(sessionId: string): Promise<any | null> {
const key = `${this.prefix}${sessionId}`;
try {
const data = await this.client.get(key);
return JSON.parse(data);
} catch (error) {
return null;
}
}
async extendSession(sessionId: string): Promise<void> {
const key = `${this.prefix}${sessionId}`;
await this.client.expire(key, 86400); // Extend to 24 hours
}
async deleteSession(sessionId: string): Promise<void> {
const key = `${this.prefix}${sessionId}`;
await this.client.delete(key);
}
private generateSessionId(): string {
return Math.random().toString(36).substring(2) + Date.now().toString(36);
}
}
// Usage
const sessionManager = new SessionManager(stringClient);
const sessionId = await sessionManager.createSession("user123", {
userId: "user123",
loginTime: new Date().toISOString(),
permissions: ["read", "write"],
});
const session = await sessionManager.getSession(sessionId);
Configuration Management
class ConfigManager {
private client: any;
private prefix = "config:";
constructor(client: any) {
this.client = client;
}
async setConfig(key: string, value: any): Promise<void> {
const configKey = `${this.prefix}${key}`;
await this.client.set(configKey, JSON.stringify(value));
}
async getConfig<T>(key: string, defaultValue?: T): Promise<T | null> {
const configKey = `${this.prefix}${key}`;
try {
const data = await this.client.get(configKey);
return JSON.parse(data);
} catch (error) {
return defaultValue || null;
}
}
async deleteConfig(key: string): Promise<void> {
const configKey = `${this.prefix}${key}`;
await this.client.delete(configKey);
}
}
// Usage
const configManager = new ConfigManager(stringClient);
await configManager.setConfig("app.settings", {
theme: "dark",
language: "en",
notifications: true,
});
const settings = await configManager.getConfig("app.settings");
API Reference
Methods
Method | Description | Parameters | Returns |
---|---|---|---|
set(key, value, ttl?) | Set a string value | key: string, value: string, ttl?: number | Promise<void> |
get(key) | Get a string value | key: string | Promise<string> |
delete(key) | Delete a key | key: string | Promise<void> |
exists(key) | Check if key exists | key: string | Promise<boolean> |
ttl(key) | Get remaining TTL | key: string | Promise<number> |
expire(key, ttl) | Set TTL for key | key: string, ttl: number | Promise<void> |
batch(operations) | Batch operations | operations: Array<BatchOperation> | Promise<Array<any>> |
Batch Operation Types
interface BatchOperation {
type: "set" | "get" | "delete" | "exists" | "ttl" | "expire";
key: string;
value?: string;
ttl?: number;
}
Next Steps
- Set Operations - Learn about set operations
- WebSocket Operations - Learn about WebSocket operations
- API Reference - Explore the complete REST API documentation
TypeScript Configuration
For optimal TypeScript support, ensure your tsconfig.json
includes:
{
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
Best Practices
- Type Safety: Always use TypeScript for better development experience
- Error Handling: Implement proper error handling for all operations
- Connection Management: Reuse client instances when possible
- Batch Operations: Use MSET/MGET for multiple operations
- Expiration: Set appropriate TTL values for temporary data
- Key Naming: Use consistent key naming conventions
Performance Tips
- Use batch operations (MSET/MGET) instead of individual calls
- Implement connection pooling for high-throughput applications
- Consider using WebSocket client for real-time applications
- Cache frequently accessed values in your application layer
- Use appropriate data types (strings for text, numbers for counters)