0.8.1 • Published 4 years ago

dynamodb-quickly v0.8.1

Weekly downloads
-
License
MIT
Repository
-
Last release
4 years ago

dynamodb-quickly

Lightweight client library for working with DynamoDB in Node.js. Written in Typescript with a Promise-based API.

This library tries to expose the natural DynamoDB way of doing things as directly as possible, while adding a few convenient helpers and shortcuts.

Things it does:

  • Supports reading and writing items as plain Javascript objects. (more details below)
  • Adds a few convenience patterns and shortcuts.
  • Handles some common patterns for you, like using attribute_not_exists() expressions.

Things it does NOT do:

  • Doesn't have a schema or do any data validation.
  • Doesn't provide a DAO style interface.

Also note, so far this library is just a partial implementation of the DynamoDB API. Some big features missing are: no helpers for Query or Scan.

Javascript data mapping

One thing this library does is automatically map from Javascript to Dynamo's AttributeValue tagging scheme. The mapping looks like:

plain Javascript objectAttributeValue
null or undefined{ NULL: true }
typeof is string{ S: ... }
typeof is boolean{ BOOL: ... }
typeof is number{ N: ... }
Array.isArray is true{ L: [ ... ] } (aka List)
all other values{ M: { ... } } (aka Map)

Usage

Connecting to the database

To get started, you should install and initialize the aws-sdk library seperately (version 2.322.0 or later should work), then create a new DynamoDB service object. Example:

import AWS from 'aws-sdk';

const client = new AWS.DynamoDB({
    apiVersion: '2012-08-10',
    region: 'us-east-1'
    endpoint: endpoint
});

Setting up the table

Once you have the client instance, create one or more Table instances.

import { Table } from 'minimal-dynamodb-client'

const table = new Table({
    client,
    tableName: 'my-table',
    primaryKey: 'key'
});

The primaryKey is optional but highly recommended, This should be the field name for the table's primary key. (or one of them, if there are multiple). If provided, this library will use it for some convenient patterns.

Local development

When running locally it's recommended that devs launch this awesome Docker container:

    docker run -p 7042:8000 -it --rm instructure/dynamo-local-admin

Once running you can use the web interface at http://localhost:7042 to browse your data.

Setting up tables

This library adds a CreateTable helper. It's recommended to call this when the app is running locally, to set up all your table(s) on the local DynamoDB instance.

Example:

if (localMode) {
    await table.createTable();
}

It's not recommended to use createTable in production. Instead your production tables should be configured by a seperate process. (using Terraform or CDK or etc)

API

async table.getItem(key)

Calls GetItem.

The 'key' can either be a string or an object.

If the key is a string, then we fetch the item with that primary key value. (using the table's 'primaryKey')

If the key is an object, then it's converted to an AttributeValue map (see below) and then used as the "Key" value

Examples:

data = await table.getItem("user-123");

data = await table.getItem({ specificPrimaryKey: "value-123" });

async table.putItem(itemData, options?)

Calls PutItem.

itemData is the object to set. This object should include one of the table's primary keys, or else Dynamo will complain.

Available options:

optiondescription
noOverwriteDon't overwrite this item if it already exists. (using an attribute_not_exists expression)
primaryKeyKey to use with noOverwrite (defaults to the table's primaryKey)

Examples:

await table.putItem({
    key: 'user-123',
    name: 'Name',
    address: '123 Address'
})

await table.putItem(userData, { noOverwrite: true });

async table.updateItem(key: string | object, changes: array | object)

Calls UpdateItem

key is either a string or object, and works the same as the key in getItem. If it's a string then the table's primaryKey is used.

changes is either an Array of {field, value} objects, or a single object of fields to set. Dynamo allows you to change multiple fields in a single item with one operation.

Example - object format

// Set a single field "name" to value "Alice":
await table.updateItem(key, { name: 'Alice' })

// Set "name" to "Alice" and "city" to "Denver"
await table.updateItem(key, { name: 'Alice' city: 'Denver' })

Example - array format

// Set a single field "name" to value "Alice":
await table.updateItem(key, [{ field: 'name', value: 'Alice' }])

// Set "name" to "Alice" and "city" to "Denver"
await table.updateItem(key, [{ field: 'name', value: 'Alice' },{ field: 'city', value: 'Denver' }])

Advanced example - array format with nested field

If the item has nested Map values, then we can update the contents of those maps. For this, you can call updateItem with an array of changes, and pass a list as the field.

For example, let's say that the item is:

{
  key: 'user123',
  name: 'Alice',
  friends: {
    user456: {
      accepted: false
    }
  }
}

We can update the nested "accepted" value with:

await table.updateItem(key, [{
    field: [ 'friends', 'user456', 'accepted' ],
    value: true
}])

table.deleteItem(key)

Calls DeleteItem

The key takes the same values as getItem().

Example:

await table.deleteItem(key);

table.deleteFields(key, fields: string[])

Deletes one or more fields out of an item. This uses UpdateItem with a REMOVE expression. The key takes the same values as getItem().

await table.deleteFields(key, [ "needsMigration" ]);

table.deleteField(key, field: string)

Deletes one field from an item. Convenience method for calling deleteFields with a single item.

await table.deleteField(key, "needsMigration");

table.listAppend(key, field: string, value)

Appends an item onto a list value. This uses UpdateItem with a list_append() expression. The key takes the same values as getItem().

Example:

If the item is equal to:

{
    key: 'key1',
    list: ['a', 'b']
}

Then we can add an item with

await table.listAppend('key1', 'list', 'c')