Skip to content

Specs for a simple Key/Value (plus Secondary Indexes) store API, for Node.js/Javascript

License

Notifications You must be signed in to change notification settings

interop-alliance/kvplus-js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 

Repository files navigation

kvplus-js

Specs for a simple Key/Value (plus Secondary Indexes) store API, for Node.js/Javascript

Contents

Motivation

This K/V API was created to provide a pluggable persistence interface for the oidc-op OpenID Connect Identity Provider library (to store user accounts, client registrations, access tokens, and so on).

Store API

Creating a Store Instance

Usage:

var options = {
  path: './db',
  serialize: (obj) => { return JSON.stringify(obj) }
}
var store = new KVPlusStore(options)
Constructor Options
  • path - (string) For filesystem based stores, specifies the directory where the store will be created. Optional.
  • serialize - (Function) If storing objects other than strings, provide a serialization function that will turn an object into a string representation. Can also be provided for the whole store (in the store constructor), or overridden for each collection.

Initializing a Collection

Promise<> createCollection (string collectionName, Object options = {})

Creates/initializes a collection in the store. This operation should be idempotent -- if the collection already exists, it should result in a no-op. Think of it as likely to run each time an app server starts up (instead of only once, at install time or in a database migration).

Collection options
  • serialize - (Function) If storing objects other than strings, provide a serialization function that will turn an object into a string representation. Can also be provided for the whole store (in the store constructor), or overridden for each collection.

Usage:

let serialize = (obj) => { return JSON.stringify(obj) }
store.createCollection('users', { serialize })
  .then(() => {
    // collection created/initialized
  })

CRUD API

exists()

Promise<Boolean> exists (string collectionName, string key)

Checks whether an object exists in the collection, for a given key.

Usage:

store.exists('users', 'u1')
  .then(found => {
    if (found) {
      // user exists!
    } else {
      // not found
    }
  })

get()

Promise<Object> get (string collectionName, string key)

Retrieves the serialized object from the store, from the given collection.

Usage:

store.get('users', 'u1')
  .then(retrievedUser => {
    console.log(retrievedUser)  // user object with key 'u1' retrieved
  })

put()

Promise<Object> put (string collectionName, string key, Object data)

Writes an object to the store, and returns the object that was written. (If an object already exists for that key, in that collection, it gets overwritten.)

Usage:

store.put('users', 'u2', { name: 'Alice' })
  .then(storedUser => {
    assert(storedUser.name === 'Alice')
  })

remove()

Promise<Boolean> remove (string collectionName, string key)

Attempts to remove an object for a given collection and key. If the object existed and the delete succeeded, resolves to true. If the object did not exist, resolves to false.

Usage:

store.remove('users', 'u2')
  .then(() => {
    // user deleted. In this case, we don't care about whether the user actually
    // existed, so we're not going to check the boolean result of the operation
  })

Secondary Index API

createIndex()

Promise<> createIndex (string collectionName, string property)

Creates a secondary index on a given object property, and enables subsequent secondary queries on that field. Should be idempotent (if the index already exists, results in no-op).

Usage:

store.createIndex('users', 'email')
  .then(() => {
    // secondary index created on the 'email' property of users objects.
    // you can now perform findBy() queries on this property
  })

findBy()

Promise<Array<Object>> findBy (string collectionName, string property, string value)

Performs a secondary index query (exact matches only, for now) on a given existing index and value.

Usage:

store.findBy('users', 'email', '[email protected]')
  .then(results => {
    console.log(results)  // -> [ { name: 'Alice', email: '[email protected]'} ]
  })

Implementations

The following are in-progress implementations.

  • In-memory KVPlus store. (For reference / testing)

Questions/Design Decisions

  • Should there be a list(collectionName) api method? issue #1
  • Should there be a way to list all collections? (created explicitly or lazily) issue #3

About

Specs for a simple Key/Value (plus Secondary Indexes) store API, for Node.js/Javascript

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published