An open API service indexing awesome lists of open source software.

https://github.com/baseline-js/dynamodb

DynamoDB library for simple and optimized way to use AWS DynamoDB
https://github.com/baseline-js/dynamodb

Last synced: 8 months ago
JSON representation

DynamoDB library for simple and optimized way to use AWS DynamoDB

Awesome Lists containing this project

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](#installation)
- [Quick Start](#quick-start)
- [Establishing a Connection](#establishing-a-connection)
- [Creating an item](#creating-an-item)
- [Getting a single item](#getting-a-single-item)
- [Updating an item](#updating-an-item)
- [Deleting an item](#deleting-an-item)
- [Retrieving all items](#retrieving-all-items)
- [Querying items](#querying-items)
- [Extended Usages](#extended-usages)
- [Batch Get](#batch-get)
- [Batch Create](#batch-create)
- [Batch Delete](#batch-delete)
- [Query Range](#query-range)
- [Query Range Between](#query-range-between)
- [Create, Update, Delete Conditions](#create-update-delete-conditions)
- [Limit](#limit)
- [Projection Expressions](#projection-expressions)
- [Utility Functions](#utility-functions)
- [Unmarshalling](#unmarshalling)
- [Marshalling](#marshalling)
- [Error Handling](#error-handling)
- [Environment Variables](#environment-variables)
- [Serverless Offline](#serverless-offline)

## Installation

```sh
npm install @baselinejs/dynamodb
```

```sh
yarn add @baselinejs/dynamodb
```

```sh
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](#environment-variables) for more information.

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

### Creating an item

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

```ts
const user = await putItem({
dynamoDb: dynamo,
table: 'user-table-staging',
item: { userId: '123', email: 'example@example.com', name: 'Alice' },
});
```

### Getting a single item

Get a single item from your table.

```ts
const user = await getItem({
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.

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

### Deleting an item

Delete an item from your table.

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

### Retrieving all items

Fetch all items from a table.

```ts
const allUsers = await getAllItems({
dynamoDb: dynamo,
table: 'user-table-staging',
});
```

### Querying items

Query items from an index.

```ts
const users = await queryItems({
dynamoDb: dynamo,
table: 'user-table-staging',
keyName: 'email',
keyValue: 'example@example.com',
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.

```ts
const users = await batchGetItems({
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.

```ts
const users = await batchPutItems({
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.

```ts
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.

```ts
const userPurchases = await queryItemsRange({
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`

```ts
const userPurchases = await queryItems({
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.

```ts
const userPurchases = await queryItemsRangeBetween({
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`

```ts
const userPurchases = await queryItems({
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.

```ts
try {
const user = await putItem({
dynamoDb: dynamo,
table: 'user-table-staging',
item: { userId: '123', email: 'example2@example.com', 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.

```ts
const userPurchases = await queryItems({
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.

```ts
const userPurchases = await queryItems({
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.

```ts
const user = unmarshallItem(record.dynamodb?.NewImage);
```

### Marshalling

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

```ts
const user = {
userId: '123',
email: 'example@example.com',
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.