UNPKG

@baselinejs/dynamodb

Version:

DynamoDB library for simple and optimized way to use AWS DynamoDB

377 lines (291 loc) 8.92 kB
# Baseline DynamoDB <!-- omit in toc --> 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 <!-- omit in toc --> - 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 <!-- omit in toc --> - [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<User>({ 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<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. ```ts 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. ```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<User>({ dynamoDb: dynamo, table: 'user-table-staging', }); ``` ### Querying items Query items from an index. ```ts const users = await queryItems<User>({ 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<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. ```ts 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. ```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<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` ```ts 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. ```ts 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` ```ts 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. ```ts try { const user = await putItem<User>({ 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<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. ```ts 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. ```ts const user = unmarshallItem<User>(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.