@politico/dynamo-records
v1.0.3
Published
A utility library to simplify working with AWS DynamoDB records
Downloads
49
Maintainers
Keywords
Readme
@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 = '[email protected]';
// 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!',
});
};