npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@baselinejs/dynamodb

v0.2.4

Published

DynamoDB library for simple and optimized way to use AWS DynamoDB

Downloads

307

Readme

Baseline DynamoDB

Baseline DynamoDB is an optimized utility library that simplifies standard DynamoDB operations. It's focused towards multi table designed applications, and aims to provide a set of functions that are tailored to the specific use cases of these applications.

Features

  • Simplified Item Operations: CRUD with less boilerplate code.
  • Advanced Querying: Easily use sort key conditions, including begins_with and between, to filter queries.
  • Batch Operations: Automatically handles chunking for batch get, batch create, and batch delete operations.
  • Lightweight

Table of Contents

Installation

npm install @baselinejs/dynamodb
yarn add @baselinejs/dynamodb
pnpm install @baselinejs/dynamodb

Quick Start

Establishing a Connection

First create a connection to your DynamoDB table.

Must specify a region.

Natively handles both local and deployed environments. See Environment Variables for more information.

const dynamo = getDynamodbConnection({
  region: 'us-east-1',
});

Creating an item

Add a new item to your table, providing the previously created connection.

const user = await putItem<User>({
  dynamoDb: dynamo,
  table: 'user-table-staging',
  item: { userId: '123', email: '[email protected]', name: 'Alice' },
});

Getting a single item

Get a single item from your table.

const user = await getItem<User>({
  dynamoDb: dynamo,
  table: 'user-table-staging',
  key: {
    userId: '123',
  },
});

Updating an item

Update an item in your table.

Key properties will be automatically removed from fields to prevent attribute errors.

const updatedUser = await updateItem<User>({
  dynamoDb: dynamo,
  table: 'user-table-staging',
  key: {
    userId: '123',
  },
  fields: {
    name: 'Bob',
  },
});

Deleting an item

Delete an item from your table.

const deletedUser = await deleteItem({
  dynamoDb: dynamo,
  table: 'user-table-staging',
  key: {
    userId: '123',
  },
});

Retrieving all items

Fetch all items from a table.

const allUsers = await getAllItems<User>({
  dynamoDb: dynamo,
  table: 'user-table-staging',
});

Querying items

Query items from an index.

const users = await queryItems<User>({
  dynamoDb: dynamo,
  table: 'user-table-staging',
  keyName: 'email',
  keyValue: '[email protected]',
  indexName: 'email-index',
});

Extended Usages

Batch Get

Batch get items from a table Automatically handles splitting the keys into chunks of 100.

Returned item order is not necessarily the same as the input order.

const users = await batchGetItems<User>({
  dynamoDb: dynamo,
  table: 'user-table-staging',
  keys: [{ userId: '123' }, { userId: '456' }],
});

Batch Create

Batch create items into a table. Automatically handles splitting the items into chunks of 25.

const users = await batchPutItems<User>({
  dynamoDb: dynamo,
  table: 'user-table-staging',
  items: [
    { userId: '123', name: 'Alice' },
    { userId: '456', name: 'Bob' },
  ],
});

Batch Delete

Batch delete items from a table. Automatically handles splitting the keys into chunks of 25.

const isDeleted = await batchDeleteItems({
  dynamoDb: dynamo,
  table: 'user-table-staging',
  keys: [{ userId: '123' }, { userId: '456' }],
});

Query Range

Query items from a table with a range key.

const userPurchases = await queryItemsRange<Purchase>({
  dynamoDb: dynamo,
  table: 'purchase-table-staging',
  keyName: 'userId',
  keyValue: '123',
  rangeKeyName: 'createdAt',
  rangeKeyValue: '2022',
  // Fuzzy search will use a begins_with condition
  fuzzy: true,
  indexName: 'userId-createdAt-index',
});

Equivalent query using queryItems

const userPurchases = await queryItems<Purchase>({
  dynamoDb: dynamo,
  table: 'purchase-table-staging',
  keyName: 'userId',
  keyValue: '123',
  indexName: 'userId-createdAt-index',
  rangeCondition: {
    operator: 'BeginsWith',
    field: 'createdAt',
    value: '2022',
  },
});

Query Range Between

Query items from a table with a range key between two values.

const userPurchases = await queryItemsRangeBetween<Purchase>({
  dynamoDb: dynamo,
  table: 'purchase-table-staging',
  keyName: 'userId',
  keyValue: '123',
  rangeKeyName: 'createdAt',
  rangeKeyValueMin: '2022-01-01T00:00:00.000Z',
  rangeKeyValueMax: '2023-01-01T00:00:00.000Z',
  indexName: 'userId-createdAt-index',
});

Equivalent query using queryItems

const userPurchases = await queryItems<Purchase>({
  dynamoDb: dynamo,
  table: 'purchase-table-staging',
  keyName: 'userId',
  keyValue: '123',
  indexName: 'userId-createdAt-index',
  rangeCondition: {
    operator: 'Between',
    field: 'createdAt',
    value: '2022-01-01T00:00:00.000Z',
    betweenSecondValue: '2023-01-01T00:00:00.000Z',
  },
});

Create, Update, Delete Conditions

A conditions array can be provided to the putItem, updateItem, and deleteItem functions to specify conditions that must be met for the operation to succeed.

Conditions are combined with AND.

try {
  const user = await putItem<User>({
    dynamoDb: dynamo,
    table: 'user-table-staging',
    item: { userId: '123', email: '[email protected]', name: 'Alice' },
    conditions: [
      {
        // Only create if this userId does not already exist
        operator: 'AttributeNotExists',
        field: 'userId',
      },
    ],
  });
} catch (error) {
  if (error.name === 'ConditionalCheckFailedException') {
    // error.Item contains the item that already exists with the specified userId
  }
}

Limit

You can limit the number of items returned by specifying the limit parameter. This applies to the query functions as well as the getAllItems function.

The function will handle pagination internally up until the limit is reached.

const userPurchases = await queryItems<Purchase>({
  dynamoDb: dynamo,
  table: 'purchase-table-staging',
  keyName: 'userId',
  keyValue: '123',
  limit: 10,
});

Projection Expressions

Projection expressions are used to limit the attributes returned from a query to only the specified fields.

To maintain type safety, you can specify the fields you want to return using the second generic type parameter.

const userPurchases = await queryItems<Purchase, 'userId' | 'createdAt'>({
  dynamoDb: dynamo,
  table: 'purchase-table-staging',
  keyName: 'userId',
  keyValue: '123',
  projectionExpression: ['userId', 'createdAt'],
});

Utility Functions

Unmarshalling

Unmarshalling is used to convert a DynamoDB record into a JavaScript object.

This is useful when using dynamodb streams, as the new and old images are returned as DynamoDB records that need to be unmarshalled.

const user = unmarshallItem<User>(record.dynamodb?.NewImage);

Marshalling

Marshalling is used to convert a JavaScript object into a DynamoDB record.

const user = {
  userId: '123',
  email: '[email protected]',
  name: 'Alice',
};
const marshalledUser = marshallItem(user);

Error Handling

Errors are not caught internally but are instead propagated up to the calling code.

To handle these errors effectively, wrap function calls in try-catch blocks in your application. This allows for custom error handling strategies, such as logging errors or retrying failed operations.

Environment Variables

Serverless Offline

IS_OFFLINE

Will be "true" in your handlers when using serverless-offline. When "true" will use values appropriate to work with DynamoDB Local.

region: "localhost",
endpoint: "http://localhost:8000",

FORCE_ONLINE

Set to "true" to override the IS_OFFLINE environment variable and use a deployed DynamoDB instance.