Skip to content

An intuitive DynamoDB request building API for JavaScript

Notifications You must be signed in to change notification settings

jvan100/dynamo-request-builder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dynamo Request Builder

An intuitive DynamoDB request building API for JavaScript.

Contents

Installation

npm install dynamo-request-builder

Creating Requests

Use the DynamoRequestBuilderCreator with a DynamoDB DocumentClient to create a DynamoRequestBuilder.

import DynamoRequestBuilderCreator from "dynamo-request-builder";

const requestBuilder = new DynamoRequestBuilderCreator(dynamoDocClient).create("table_name");

Delete

import { attribute, sizeOf } from "dynamo-request-builder/attributes";
import { or } from "dynamo-request-builder/operators";
import { ReturnValues } from "dynamo-request-builder/return-values";

const request = requestBuilder.delete("partitionKeyName", "partitionKeyValue")
  .withSortKey("sortKeyName", "sortKeyValue") // Sort key condition
  .onlyIfAttribute("attribute").eq("value") // Add an attribute condition
  .onlyIfSizeOfAttribute("attribute").lte(1) // Add a size of attribute condition
  .onlyIf(
    or(attribute("attribute1").gte(1), attribute("attribute2").contains("value")),
    sizeOf("attribute3").eq(2)
  ) // Add multiple attribute conditions
  .returnValues(ReturnValues.AllOld); // Specify values to return

Get

const request = requestBuilder.get("partitionKeyName", "partitionKeyValue")
  .withSortKey("sortKeyName", "sortKeyValue") // Sort key condition
  .getAttributes("attribute", "attribute[0]", "attribute[0].subAttribute") // Specify attributes to retrieve
  .consistentRead(); // Use consistent read

Put

import { attribute, sizeOf } from "dynamo-request-builder/attributes";
import { not } from "dynamo-request-builder/operators";
import { ReturnValues } from "dynamo-request-builder/return-values";

const item = {
  ...
};

const request = requestBuilder.put(item)
  .ifItemNotExists("partitionKeyName", "sortKeyName") // Only put the item if it doesn't already exist
  .onlyIfAttribute("attribute").eq("value") // Add an attribute condition
  .onlyIfSizeOfAttribute("attribute").lte(1) // Add a size of attribute condition
  .onlyIf(
	  not(attribute("attribute1").gte(1)),
	  sizeOf("attribute3").eq(2)
  ) // Add multiple attribute conditions
  .returnValues(ReturnValues.AllOld); // Specify values to return

Query

import { attribute, sizeOf } from "dynamo-request-builder/attributes";
import { or } from "dynamo-request-builder/operators";

const request = requestBuilder.query("partitionKeyName", "partitionKeyValue")
  .whereSortKey("sortKeyName").beginsWith("value") // Add a sort key condition
  .whereAttribute("attribute").eq("value") // Add an attribute condition
  .whereSizeOfAttribute("attribute").lt(1) // Add a size of attribute condition
  .where(
    or(attribute("attribute1").gte(1), attribute("attribute2").contains("value")),
    sizeOf("attribute3").eq(2)
  ) // Add multiple attribute conditions
  .getAttributes("attribute", "attribute[0]", "attribute[0].subAttribute") // Specify attributes to retrieve
  .limit(5) // Specify a limit on the number of items to return
  .useIndex("indexName") // Specify an index to use
  .scanIndexDescending(); // Scan the index in descending order

Scan

import { attribute, sizeOf } from "dynamo-request-builder/attributes";
import { or } from "dynamo-request-builder/operators";

const request = requestBuilder.scan()
  .whereAttribute("attribute").eq("value") // Add an attribute condition
  .whereSizeOfAttribute("attribute").lt(1) // Add a size of attribute condition
  .where(
    or(attribute("attribute1").gte(1), attribute("attribute2").contains("value")),
    sizeOf("attribute3").eq(2)
  ) // Add multiple attribute conditions
  .getAttributes("attribute", "attribute[0]", "attribute[0].subAttribute") // Specify attributes to retrieve
  .limit(5) // Specify a limit on the number of items to return
  .useIndex("indexName") // Specify an index to use

Update

import { attribute, sizeOf, update } from "dynamo-request-builder/attributes";
import { or } from "dynamo-request-builder/operators";

const request = requestBuilder.update("partitionKeyName", "partitionKeyValue")
  .withSortKey("sortKeyName", "sortKeyValue") // Sort key condition
  .updateAttribute("attribute").incrementBy(5) // Add an update operation
  .operations(update("attribute1").add(1, 2, 3), update("attribute2").remove()) // Add multiple update operations
  .onlyIfAttribute("attribute").eq("value") // Add an attribute condition
  .onlyIfSizeOfAttribute("attribute").lte(1) // Add a size of attribute condition
  .onlyIf(
    or(attribute("attribute1").gte(1), attribute("attribute2").contains("value")),
    sizeOf("attribute3").eq(2)
  ) // Add multiple attribute conditions
  .returnValues(UpdateReturnValues.UpdatedNew); // Specify values to return

You can check the generated request parameters for yourself by accessing request.params.

Attributes

The ability to select specific attributes and apply constraint conditions and update operations to them are needed for certain expressions.

Attribute Type Attribute Selectors Use Cases Methods
Condition Attribute attribute(attributePath), sizeOf(attributePath) Condition Expressions
  • onlyIfAttribute(attributePath)
  • onlyIfSizeOfAttribute(attributePath)
  • onlyIf(...conditionExpressions)

Filter Expressions
  • whereAttribute(attributePath)
  • whereSizeOfAttribute(attributePath)
  • where(...filterExpressions)

Key Condition Expressions
  • whereSortKey(sortKeyName)
  • beginsWith(subString) - Check if the string attribute begins with a substring
  • between(value1, value2) - Check if the numerical attribute is between two values
  • eq(value) - Check if the attribute is equal to a value
  • ne(value) - Check if the attribute is not equal to a value
  • lt(value) - Check if the numerical attribute is less than a value
  • gt(value) - Check if the numerical attribute is greater than a value
  • lte(value) - Check if the numerical attribute is less than or equal to a value
  • gte(value) - Check if the numerical attribute is greater than or equal to a value
  • exists() - Check if the attribute exists
  • notExists() - Check if the attribute doesn't exist
  • contains(value) - Check if a string contains a substring or a set or list contains an element
  • notContains(value) - Check if a string doesn't contain a substring or a set or list doesn't contain an element
  • ofType(type) - Check if an attribute is of a type
  • in(...values) - Check if an attribute is in a list of values
Update Operation Attribute update(attributePath) Update Expressions
  • updateAttribute(attributePath)
  • operations(...updateExpressions)
  • add(...values) - Add a numerical value to the numerical attribute or values to the set attribute
  • increment() - Increment the numerical attribute by 1
  • incrementBy(value) - Increment the numerical attribute by a value
  • decrement() - Decrement the numerical attribute by 1
  • decrementBy(value) - Decrement the numerical attribute by a value
  • appendToStartOfList(...values) - Append values to the start of the list attribute
  • appendToEndOfList(...values) - Append values to the end of the list attribute
  • set(value, ifNotExists = false) - Set the value of the attribute (optional only set the value if the attribute doesn't exist)
  • remove() - Remove the attribute
  • removeFromListAt(...indices) - Remove elements from the list attribute at the specific indices
  • removeFromSet(...values) - Remove values from the set attribute

Logical Operators

Logical operators are used to extend the logic of condition expressions, filter expressions and key condition expressions.

Operator Description
not(conditionExpression) The condition expression must evaluate to false for the result to be true
and(...conditionExpressions) All condition expressions must evaluate to true for the result to be true
or(...conditionExpressions) Only one condition expression must evaluate to true for the result to be true

Executing Requests

Once a request has been created, it can be executed and the return values can be used.

Request Type Inheriting Types Methods
BaseRequest All execFullResponse() - Execute and return the full response
ReadManyRequest QueryRequest, ScanRequest
  • exec() - Execute and return requested items
  • execCount() - Execute and return the count of the number of items found
  • execSingle() - Execute and return a single item
WriteRequest DeleteRequest, PutRequest, UpdateRequest exec() - Execute and return requested attributes
GetRequest None exec() - Execute and return the requested item