Dev Guide
Dev GuideUser GuideGitHubNuGetDevCommunitySubmit a ticketLog In
GitHubNuGetDevCommunitySubmit a ticket

Key value store

Store customer data using the key value store in Optimizely Connect Platform (OCP).

The key value store is a general-purpose key-value storage for temporary or long-term storage of small to medium-sized data sets/objects. Similar to the secrets store, the key value store provides atomic operations such as patch, but also includes increment, list, and set operations. The interface for the key value store extends the same interface as the secrets and settings store, so the basic operations are similar.

For more information, see the App SDK documentation.

🚧

Important

Do not write sensitive data such as API keys, API tokens, usernames, or passwords to the key value store. While the data is encrypted at rest, it does not have the same level of security as the secrets or setting stores and is not suitable for storing sensitive information.

Manage objects in the key value store

As with the secrets store, you can write a hash of primitive values such as string, number, boolean, array, and any other value that you can serialize with JSON.stringify. One major difference from the secrets store is the key value store returns the previous value (if there was one).

import {storage} from '@zaiusinc/app-sdk';
const order = {id: 123, status: 'pending'};
const previousValue = await storage.kvStore.put(`pending_order|${order.id}`, order);

Set a TTL on all your short-term data stored in the key value store to avoid never-ending growth. Setting a TTL allows your data to expire and automatically be purged from the key value store. If you attempt to read or update an object that has expired, you get the same result as if the value never existed.

// Expire the order after 10 minutes
await storage.kvStore.put(`pending_order|${order.id}`, order, {ttl: 600});

To read an object from the key value store:

interface PendingOrder {
  id: number;
  status: string;
}

const pendingOrder = await storage.kvStore.get<PendingOrder>(`pending_order|${orderId}`);
if (pendingOrder.status === 'pending') {
  // TODO
}

To update an object in the key value store:

await storage.kvStore.patch(`pending_order|${orderId}`, {status: 'completed'});

// You can also enforce type safety
await storage.kvStore.patch<Partial<PendingOrder>>(key, update);

You can also perform more complicated updates with a callback:

interface Countdown {
  counter: number;
  step: number;
}
await storage.kvStore.patch('countdown', (value, options) => {
  // set the TTL to 60 seconds
  options.ttl = 60;
  // change the value
  value.counter -= value.step || 1;
  if (value.counter < 0) {
    value.counter = 0;
  }
  // return the value we want to set given the previous value
  return value;
});

📘

Note

You can call the update callback multiple times in order to ensure the operation completes atomically.

To check if an object exists in the key value store:

if (await storage.kvStore.exists(`pending_order|${orderId}`)) {
  // we've already seen the order
}

To delete an object from the key value store:

await storage.kvStore.delete(`pending_order|${orderId}`);

Features of the key value store

Increment

If you need a consistent counter across all instances of your app (for example, to count the number of generated coupons you have remaining), use the increment method to atomically increment or decrement a value in the key value store.

// Add one to the counter because we generated a new summer15 coupon
let remaining = await storage.kvStore.increment('coupons', 'summer15');

// subtract 5 from the counter because we just used 5 coupons
remaining = await storage.kvStore.increment('coupons', 'summer15', -5);

// add 10 to both our coupons
await storage.kvStore.incrementMulti('coupons', {summer15: 10, freeship: 10});

Lists (arrays)

The key value tore supports special atomic operations on lists. For more detailed information, see the App SDK documentation. List operations include:

  • append or appendMulti – Atomically add one or more elements to the end of a list (or multiple lists).
  • peek or peekMulti – Retrieve (without removing) one or more elements from the front of the list (or multiple lists).
  • shift or shiftMulti – Atomically remove (and retrieve) one or more elements from the front of the list (or multiple lists).
  • unshift or unshiftMultiAtomically – Insert one or more elements at the front of a list (or multiple lists).

Sets

You can also use the key value store to maintain a set of strings or numbers. In order to create a set of strings or numbers, write a StringSet or NumberSet object to the key value store. When you read the set back, it is an instance of a StringSet or NumberSet.