Database

Key-value storage and serverless scripts

The Database module provides key-value storage and serverless script execution.

Put Data

POST /v1/operations/data
SDK: sdk.database.putData()

Store data with a key.

const result = await sdk.database.putData({
key: 'user:preferences:usr_abc123',
value: {
  theme: 'dark',
  language: 'en',
  notifications: true
},
ttl: 86400 * 30 // 30 days in seconds
});

Parameters

Name Type Description
key required string Unique key for the data
value required any Data to store (JSON serializable)
ttl optional number Time-to-live in seconds

Scan Data

GET /v1/operations/data
SDK: sdk.database.scanData()

Retrieve data by key or prefix.

// Get single key
const result = await sdk.database.scanData({
  key: 'user:preferences:usr_abc123'
});

if (result.ok) {
  console.log(result.val.value);
}

// Scan by prefix
const prefixResult = await sdk.database.scanData({
  prefix: 'user:preferences:',
  limit: 100
});

if (prefixResult.ok) {
  prefixResult.val.items.forEach(item => {
    console.log(item.key, item.value);
  });
}

Parameters

Name Type Description
key optional string Exact key to retrieve
prefix optional string Key prefix to scan
cursor optional string Pagination cursor
limit optional number Max items to return

Delete Data

DELETE /v1/operations/data
SDK: sdk.database.deleteData()

Delete data by key.

const result = await sdk.database.deleteData({
  key: 'user:preferences:usr_abc123'
});

Run Script

POST /v1/operations/scripts
SDK: sdk.database.runScript()

Execute a serverless script.

const result = await sdk.database.runScript({
script: 'calculate-totals',
input: {
  orderId: 'ord_xyz789',
  includeShipping: true
}
});

if (result.ok) {
console.log('Script output:', result.val);
}

Parameters

Name Type Description
script required string Script name/identifier
input optional object Input data for the script

Use Cases

Session Storage

// Store session data
await sdk.database.putData({
  key: `session:${sessionId}`,
  value: {
    userId: 'usr_abc123',
    cart: [],
    lastActivity: Date.now()
  },
  ttl: 3600 // 1 hour
});

// Retrieve session
const session = await sdk.database.scanData({
  key: `session:${sessionId}`
});

Caching

async function getProductWithCache(productId: string) {
  const cacheKey = `cache:product:${productId}`;

  // Try cache first
  const cached = await sdk.database.scanData({ key: cacheKey });

  if (cached.ok && cached.val.value) {
    return cached.val.value;
  }

  // Fetch from API
  const product = await sdk.eshop.getProduct({
    businessId: 'biz_abc123',
    id: productId
  });

  if (product.ok) {
    // Cache for 5 minutes
    await sdk.database.putData({
      key: cacheKey,
      value: product.val,
      ttl: 300
    });

    return product.val;
  }

  return null;
}

Rate Limiting

async function checkRateLimit(userId: string, action: string): Promise<boolean> {
  const key = `ratelimit:${action}:${userId}`;
  const window = 60; // 1 minute
  const maxRequests = 10;

  const result = await sdk.database.scanData({ key });

  if (result.ok && result.val.value) {
    const count = result.val.value.count;

    if (count >= maxRequests) {
      return false; // Rate limited
    }

    // Increment counter
    await sdk.database.putData({
      key,
      value: { count: count + 1 },
      ttl: window
    });
  } else {
    // First request in window
    await sdk.database.putData({
      key,
      value: { count: 1 },
      ttl: window
    });
  }

  return true;
}

Feature Flags (Simple)

// Store feature config
await sdk.database.putData({
  key: 'config:features',
  value: {
    newCheckout: true,
    darkMode: false,
    betaFeatures: ['feature-a', 'feature-b']
  }
});

// Check feature
async function isFeatureEnabled(feature: string): Promise<boolean> {
  const config = await sdk.database.scanData({
    key: 'config:features'
  });

  if (config.ok) {
    return config.val.value[feature] === true;
  }

  return false;
}

Distributed Locks

async function acquireLock(lockName: string, ttl: number = 30): Promise<boolean> {
  const key = `lock:${lockName}`;
  const lockId = crypto.randomUUID();

  const existing = await sdk.database.scanData({ key });

  if (existing.ok && existing.val.value) {
    return false; // Lock already held
  }

  await sdk.database.putData({
    key,
    value: { lockId, acquiredAt: Date.now() },
    ttl
  });

  return true;
}

async function releaseLock(lockName: string): Promise<void> {
  await sdk.database.deleteData({ key: `lock:${lockName}` });
}

// Usage
if (await acquireLock('order-processing')) {
  try {
    await processOrders();
  } finally {
    await releaseLock('order-processing');
  }
}

Key Naming Conventions

Use colons to create hierarchical keys:

user:preferences:{userId}
session:{sessionId}
cache:product:{productId}
cache:query:{hash}
ratelimit:{action}:{userId}
lock:{resource}
config:{name}
Tip

Use meaningful prefixes to organize your data and enable efficient prefix-based scans.

Warning

The key-value store is designed for simple data storage. For complex queries or relations, use your own database.