A lightweight, high-level ORM for DynamoDB that will make you fall in love with DynamoDB.
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.
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();
Because nodenamo manages the DynamoDB table for you, it has the following requirements:
- Data to be inserted into the database must be defined as a class decorated with
@DBTable()
- Properties to be saved into the database must be decorated with
@DBColumn()
- At least, one of the properties must be decorated with
@DBColumn({id:true})
to represent a unique ID. - The DynamoDB table must be created using the
nodenamo.createTable()
function or be manually created using the following schema:- A partition key named
hash
of type string. - A sort key named
range
of type string. - A GSI named
objid-index
for a string propertyobjid
and projects all.
- A partition key named
- Table creation
- Table deletion
- Insert an object
- Get an object
- List objects
- Find objects
- Update an object
- Delete an object
- Transaction
Create a table in DynamoDB to store a certain class of objects.
await nodenamo.createTable().for(T).execute();
where:
- T is a class decorated with
@DBTable()
Delete a table in DynamoDB that is used to store a certain class of objects.
await nodenamo.deleteTable().for(T).execute();
where:
T
is a class decorated with@DBTable()
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 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. Theid
is the value of a property that is tagged with@DBColumn{id:true}
T
is a class decorated with@DBTable()
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 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. Theid
is the value of a property that is tagged with@DBColumn{id:true}
T
is a class decorated with@DBTable()