Skip to content

Latest commit

 

History

History
245 lines (180 loc) · 7.45 KB

README.md

File metadata and controls

245 lines (180 loc) · 7.45 KB

nodenamo

A lightweight, high-level ORM for DynamoDB that will make you fall in love with DynamoDB.

Tests

Introduction

Nodenamo is a lightweight ORM framework for DynamoDB that is designed to wrap DynamoDB logics and allowed you to focus on designing data models and queries instead.

Example

A simple usecase without any hash/range keys

import { DBTable, DBColumn, NodeNamo } from 'nodenamo';

@DBTable()
class User
{
    @DBColumn({id:true})
    id:number

    @DBColumn()
    name:string

    @DBColumn()
    email:string

    constructor(id?:number, name?:string, email?:string)
    {
        this.id = id;
        this.name = name;
        this.email = email;
    }
}

let nodenamo = new NodeNamo({ region: 'us-east-1' });

//Create a table
await nodenamo.createTable().for(User).execute();

//Insert a user
let user = new User(1, 'Some One', '[email protected]');

await nodenamo.insert(user).into(User).execute();

//Get a user by 'id'
let user1 = await nodenamo.get(1).from(User).execute<User>();  
    /* Returns User { id: 1, name: 'Some One', email: '[email protected]' } */

//Update the user
user1.name = 'This One';
let originalUser = await nodenamo.update(user1).from(User).returning(ReturnValue.AllOld).execute(); 
    /* Returns User { id: 1, name: 'Some One', email: '[email protected]' } */

//List all users
let users = await nodenamo.list().from(User).execute<User>();
    /* Returns { items: [ User { id: 1, name: 'This One', email: '[email protected]' } ],
                 lastEvaluatedKey: undefined } */

//Delete the user by id
await nodenamo.delete(1).from(User).execute();

Requirements

Because nodenamo manages the DynamoDB table for you, it has the following requirements:

  1. Data to be inserted into the database must be defined as a class decorated with @DBTable()
  2. Properties to be saved into the database must be decorated with @DBColumn()
  3. At least, one of the properties must be decorated with @DBColumn({id:true}) to represent a unique ID.
  4. The DynamoDB table must be created using the nodenamo.createTable() function or be manually created using the following schema:
    1. A partition key named hash of type string.
    2. A sort key named range of type string.
    3. A GSI named objid-index for a string property objid and projects all.

Operations

  1. Table creation
  2. Table deletion
  3. Insert an object
  4. Get an object
  5. List objects
  6. Find objects
  7. Update an object
  8. Delete an object
  9. Transaction

Table creation

Create a table in DynamoDB to store a certain class of objects.

Example

await nodenamo.createTable().for(T).execute();

where:

  • T is a class decorated with @DBTable()

Table deletion

Delete a table in DynamoDB that is used to store a certain class of objects.

Example

await nodenamo.deleteTable().for(T).execute();

where:

  • T is a class decorated with @DBTable()

Insert an object

Insert an object into DynamoDB

await nodenamo.insert(obj).into(T).execute();

where:

  • obj is an object created from a class decorated with @DBTable()
  • T is a class decorated with @DBTable()

Get an object

Get an object from DynamoDB by the object's ID

// Get an object
await nodenamo.get(id).from(T).execute<T>();
// Get an object with a strongly consistent read
await nodenamo.get(id).from(T).stronglyConsistent(true).execute<T>();

where:

  • id is the ID of an object to be deleted. The id is the value of a property that is tagged with @DBColumn{id:true}
  • T is a class decorated with @DBTable()

List objects

List objects from DynamoDB.

//List all objects from T
await nodenamo.list().from(T).execute<T>();
//List all objects from T with a strongly consistent read
await nodenamo.list().from(T).stronglyConsistent(true).execute<T>();
//List all objects from T that have a certain hash. 
await nodenamo.list().from(T).by(hash).execute<T>();
//List all objects from T that have a certain hash and start with a certain range key value. 
await nodenamo.list().from(T).by(hash, range).execute<T>();

/***
 * Paging
 **/
//List the top 10 objects from T 
let page = await nodenamo.list().from(T).limit(10).execute<T>();
//List the next 10 objects from T and sorted in a reverse order
await nodenamo.list().from(T).limit(10).resume(page.lastEvaluatedKey).execute<T>();();

/***
 * Ordering
 **/
//List all objects from T and sorted in a reverse order
await nodenamo.list().from(T).order(false).execute<T>

/***
 * Custom index.
 **/
await nodenamo.list().from(T).using(indexName).execute<T>();

/***
 * All operations above can be chained together.
 ***/
await nodenamo.list()
              .from(T)
              .by(hash, range)
              .limit(10)
              .using(indexName)
              .order(false)
              .resume(page.lastEvaluatedKey)
              .stronglyConsistent(true)
              .execute<T>();

where:

  • T is a class decorated with @DBTable()
  • hash is the value of a hash key defined by @DBColumn({hash:true})
  • range is the prefix value of a range key defined by @DBColumn({range:true})
  • indexName is the name of an index to be used with the query.

Get an object from DynamoDB by the object's ID

// Update an object
await nodenamo.update(object).from(T).execute<T>();

// Update an object with a condition expression
await nodenamo.update(object).from(T).where(conditionExpression, expressionAttributeNames, expressionAttributeValues).execute<T>();

// Update an object and requesting for a return value.
import { ReturnValue } from 'nodenamo';

await nodenamo.update(object).from(T).returning(ReturnValue.AllOld).execute<T>();

// Update an object with a version check
await nodenamo.update(object).from(T).withVersionCheck().execute<T>();

/***
 * All operations above can be chained together.
 ***/
await nodenamo.update(obj)
              .from(T)
              .where(conditionExpression, expressionAttributeNames, expressionAttributeValues)
              .withVersionCheck()
              .returning(ReturnValue.AllNew)
              .execute<T>();

where:

  • obj is an object retrieved from the Get or List operations or an object created from a class decorated with @DBTable()
  • T is a class decorated with @DBTable()
  • conditionExpression is a string representing a conditional expression for DynamoDB's PUT operation. For example, "#name = :name"
  • expressionAttributeNames is an object representing attribute names for the conditionExpression. For example, { '#name': 'name' }
  • expressionAttributeValues is an object representing attribute values for the conditionExpression. For example, { ':name': 'Some One' }

Delete an object

Delete an object from DynamoDB by the object's ID.

await nodenamo.delete(id).from(T).execute();

where:

  • id is the ID of an object to be deleted. The id is the value of a property that is tagged with @DBColumn{id:true}
  • T is a class decorated with @DBTable()