@politico/dynamo-records
TypeScript icon, indicating that this package has built-in type declarations

1.0.3 • Public • Published

@politico/dynamo-records

This library makes working with records in AWS DynamoDB simpler and more consistent. With a few key abstractions on top of the data being stored in the database, @politico/dynamo-records provides a powerful and consistent interface for working with your data in a NoSQL context.

Basic example

In a nontrivial application, the most common pattern is to create a records interface that you then use to create multiple record types. The commented file names below are just examples; you're free to structure your code however works best for your use case.

First, you create your records interface:

// in db.js
import { makeRecordsInterface } from '@politico/dynamo-records';

const db = makeRecordsInterface({
  table: 'MyTableName', // DynamoDB table that stores our records
  namespace: 'myservice', // a prefix to add to all hash keys
});

export default db;

Then, you use your records interface to construct multiple record types:

// in users.js
import { getUnknown } from '@politico/dynamo-records';
import db from './db';

const users = db.makeRecordType({
  type: 'user', // a string that uniquely identifies this record type
  getHashKey: ({ email }) => email,
  normalizeRecord: (doc) => {
    const email = getUnknown(doc, 'email');

    if (!email || typeof email !== 'string') {
      throw new Error('user must have an email');
    }

    return {
      email,
    };
  },
});

Another record example:

// in posts.js
import { getUnknown } from '@politico/dynamo-records';
import db from './db';

const posts = db.makeRecordType({
  type: 'post',
  getHashKey: ({ email }) => `posts:${email}`,
  getRangeKey: ({ timestamp }) => timestamp,
  normalizeRecord: (doc) => {
    const email = getUnknown(doc, 'email');
    const timestamp = getUnknown(doc, 'timestamp');
    const text = getUnknown(doc, 'text', '');

    if (!email || typeof email !== 'string') {
      throw new Error('post must have an author email');
    }

    if (!timestamp || typeof timestamp !== 'string') {
      throw new Error('post must have a timestamp');
    }

    if (typeof text !== 'string') {
      throw new Error('post text must be a string');
    }

    return {
      email,
      timestamp,
      text,
    };
  },
});

Once you have your record types defined, you can use them to interact with your stored data:

// in index.js
import users from './users';
import posts from './posts';

const doSomething = async () => {
  const email = 'foo@bar.com';

  // retrieve a single record
  const someUser = await users.getRecord({ email });

  // query paginated records
  const userPosts = await posts.queryRecords({
    hash: { email }, // corresponds to input of posts.getHashKey()
    direction: 'backwards',
  });

  // add a record to the db
  await posts.putRecord({
    email,
    timestamp: new Date().toISOString(),
    text: 'Hello world!',
  });
};

Check out the docs for a more complete introduction.

Readme

Keywords

Package Sidebar

Install

npm i @politico/dynamo-records

Weekly Downloads

1

Version

1.0.3

License

ISC

Unpacked Size

69.7 kB

Total Files

45

Last publish

Collaborators

  • dlazarenko-c-nitka
  • caitlinfloyd
  • tcrite_pol
  • ewalters-politico
  • andmilligan
  • rbvea
  • mshushan-politico
  • kherbert
  • pfriedr
  • arm5077
  • wickidd
  • stilessl
  • guirreri
  • mazet
  • brizandrew
  • bzjin