Back to Arky

Database

Key-value storage and serverless scripts

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

Put Data

POST /v1/platform/data
SDK: sdk.platform.data.put()

Store data with a key.

const result = await sdk.platform.data.put({
key: 'user:preferences:usr_abc123',
value: {
  theme: 'dark',
  language: 'en',
  notifications: true
}
});

Parameters

Name Type Description
key required string Unique key for the data
value required any Data to store (JSON serializable)
previous_key optional string Optional key to delete in the same write

Scan Data

GET /v1/platform/data
SDK: sdk.platform.data.scan()

Retrieve data by exact key prefix.

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

console.log(result.value[0]?.value);

// Scan by prefix
const prefixResult = await sdk.platform.data.scan({
  key: 'user:preferences:',
  limit: 100
});

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

Parameters

Name Type Description
key required string Exact key or key prefix to scan
limit optional number Max items to return

Delete Data

DELETE /v1/platform/data
SDK: sdk.platform.data.delete()

Delete data by key.

const result = await sdk.platform.data.delete({
  key: 'user:preferences:usr_abc123'
});

Run Script

POST /v1/platform/scripts
SDK: sdk.platform.runScript()

Execute a serverless script.

const result = await sdk.platform.runScript({
name: 'migrate',
value: JSON.stringify({ dryRun: true })
});

console.log(result.success, result.message);

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.platform.data.put({
  key: `session:${sessionId}`,
  value: {
    userId: 'usr_abc123',
    cart: [],
    lastActivity: Date.now()
  },
  ttl: 3600 // 1 hour
});

// Retrieve session
const session = await sdk.platform.data.scan({
  key: `session:${sessionId}`
});

Caching

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

  // Try cache first
  const cached = await sdk.platform.data.scan({ key: cacheKey });

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

  // Fetch from API
  const product = await sdk.eshop.product.get({
    storeId: 'store_abc123',
    id: productId
  });

  if (product.ok) {
    // Cache for 5 minutes
    await sdk.platform.data.put({
      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.platform.data.scan({ key });

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

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

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

  return true;
}

Feature Flags (Simple)

// Store feature config
await sdk.platform.data.put({
  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.platform.data.scan({
    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.platform.data.scan({ key });

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

  await sdk.platform.data.put({
    key,
    value: { lockId, acquiredAt: Date.now() },
    ttl
  });

  return true;
}

async function releaseLock(lockName: string): Promise<void> {
  await sdk.platform.data.delete({ 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.