dynaorm
v1.0.17
Published
A type-safe DynamoDB ORM
Maintainers
Readme
DynaORM - A Type-Safe DynamoDB Client for TypeScript
This package provides a lightweight, type-safe client for Amazon DynamoDB, simplifying common operations with a schema-first approach. By leveraging Zod for schema validation, it ensures your data conforms to a defined structure before interacting with the database. The library abstracts away the complexities of the AWS SDK, such as marshaling and unmarshaling data, and provides a fluent API for building queries.
Key Features
- Schema-first: Define your table structure and indexes using a simple
defineSchemafunction. - Type Safety: All operations are fully typed, leveraging TypeScript's generics to provide autocompletion and prevent runtime errors.
- Zod Validation: Automatically validates data on create and upsert operations, ensuring data integrity.
- Fluent Query Builder: Construct complex queries with a chainable
query()API for intuitive read operations. - Bulk Operations: Includes methods for efficient
batchWrite,batchGet,transactWrite, andtransactGetoperations. - Throttling: Built-in support for throttling requests to manage DynamoDB throughput.
Installation
npm install dynaorm zod @aws-sdk/client-dynamodbHow to Use DynaORM
1. Define your Schema
First, define the structure of your data using Zod. This library uses Zod to validate the data before it's sent to DynamoDB. You then use the defineSchema function to specify your DynamoDB table's primary keys and any secondary indexes.
import { defineSchema } from "dynaorm";
import { z } from "zod";
const userSchema = z.object({
userId: z.string().uuid(),
email: z.string().email(),
username: z.string().min(3),
createdAt: z.string().datetime(),
status: z.enum(["active", "inactive", "suspended"]),
});
const userTableSchema = defineSchema({
tableName: "UsersTable",
fields: userSchema,
partitionKey: "userId",
globalSecondaryIndexes: {
byEmail: { partitionKey: "email", projection: { type: "ALL" } },
byStatus: {
partitionKey: "status",
sortKey: "createdAt",
projection: { type: "KEYS_ONLY" },
},
},
});2. Create the Client
The createClient function is the entry point for your application. It takes a record of your schemas and an AWS SDK client configuration. It returns a type-safe client with a model for each schema you defined.
import { DynamoDBClientConfig } from "@aws-sdk/client-dynamodb";
import { createClient } from "dynaorm";
const config: DynamoDBClientConfig = {
region: "us-east-1",
};
const client = createClient(
{ users: userTableSchema },
{
config,
modelOptions: {
throttle: { limit: 100, interval: 1000 },
},
},
);
const userModel = client.users;3. Perform Operations
Create and Upsert
const newUser = {
userId: "some-uuid-1",
email: "[email protected]",
username: "testuser",
createdAt: new Date().toISOString(),
status: "active",
};
await userModel.create(newUser);
const updatedUser = { ...newUser, status: "inactive" };
await userModel.upsert(updatedUser);Read Operations
const user = await userModel.findOne({ userId: "some-uuid-1" });
console.log(user);
const activeUsers = await userModel.findByIndex(
"byStatus",
{ status: "active" },
{ limit: 10 },
);
console.log(activeUsers);
const recentActiveUsers = await userModel
.query()
.onIndex("byStatus")
.wherePK("active")
.whereSK("begins_with", "2023-10")
.execAll();
console.log(recentActiveUsers);Update and Delete
await userModel.update({ userId: "some-uuid-1" }, { status: "suspended" });
await userModel.delete({ userId: "some-uuid-1" });Bulk Operations
await userModel.batchWrite([
{
type: "put",
item: {
userId: "uuid-2",
email: "[email protected]",
username: "userA",
createdAt: new Date().toISOString(),
status: "active",
},
},
{ type: "delete", item: { userId: "uuid-3" } },
]);
const items = await userModel.batchGet([{ userId: "uuid-2" }]);
console.log(items);
await userModel.transactWrite([
{
type: "put",
item: {
userId: "uuid-4",
email: "[email protected]",
username: "userC",
createdAt: new Date().toISOString(),
status: "active",
},
},
{
type: "update",
key: { userId: "uuid-2" },
updates: { username: "userA-updated" },
},
]);API Reference
createClient(schemas, options)
Initializes the DynamoDB client and attaches models for each schema.
- schemas: A record mapping model names to schemas.
- options: Contains
config(DynamoDBClientConfig), optionalmodelOptions, and optionalperModelOptions.
defineSchema(schema)
Defines a new DynamoDB table schema with strong typing.
- tableName: DynamoDB table name.
- fields: Zod object for item structure.
- partitionKey: Partition key field name.
- sortKey?: Optional sort key.
- globalSecondaryIndexes?: Optional GSIs.
- localSecondaryIndexes?: Optional LSIs.
Model<S>
Provides methods for interacting with a DynamoDB table.
CRUD Operations
create(item)upsert(item, options?)update(key, updates, options?)delete(key, options?)findOne(key, options?)
Query and Scan
query()findMany(partitionKeyValue, sortKeyCondition?, options?)findByIndex(indexName, keyValues, options?)scanAll(options?)getItemCount(options?)
Bulk & Transactional Operations
batchWrite(items)batchGet(keys)transactWrite(items)transactGet(keys)upsertMany(items)updateMany(items)deleteMany(partitionKeyValue, sortKeyCondition?)
QueryBuilder<S>
Fluent API for building DynamoDB Query operations.
wherePK(value)whereSK(operator, value)filter(key, operator, value, join?)limit(count)orderBy(asc)startKey(key)project(attrs)onIndex(index)consistentRead()
Execution Methods
exec()paginate()execAll()
