0.0.1-draft2 • Published 2 years ago

@piavart/nestjs-dynamodb v0.0.1-draft2

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

NestJS DynamoDB

NestJs module for working with dynamodb-data-mapper with a document-oriented approach

Install

npm install @piavart/nestjs-dynamodb

Usage

In order to create a DynamoDB connection

app.module.ts

import { Module } from '@nestjs/common';
import { DynamoDBModule } from 'nestjs-dynamodb';

import { UsersModule } from './users.module.ts';

@Module({
  imports: [
    DynamoDBModule.forRoot({
      AWSConfig: {},
      dynamoDBOptions: {},
    }),
    UsersModule,
  ],
})
export class AppModule {}

Async configuration

app.module.ts

import { Module } from '@nestjs/common';
import { DynamoDBModule } from 'nestjs-dynamodb';

@Module({
  imports: [
    DynamoDBModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: async (config: ConfigService) => ({
        AWSConfig: {
          region: 'local',
          accessKeyId: 'null',
          secretAccessKey: 'null',
        },
        dynamoDBOptions: {
          endpoint: config.get<string>('DYNAMODB_URL', 'localhost:8000'),
          sslEnabled: false,
          region: 'local-env',
        },
      }),
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}

users.module.ts

import { Module } from '@nestjs/common';
import { DynamoDBModule } from 'nestjs-dynamodb';

import { UserEntity } from './user.entity';
import { UsersService } from './users.service';

@Module({
  imports: [DynamoDBModule.forFeature([UserEntity])],
  providers: [UsersService],
})
export class UsersModule {}

To insert records to DynamoDB, you first need to create your table, for this we use dynamodb-data-mapper-annotations (under the hood). Every decorator in that package is exposed in this package as well BUT CAPITALIZED .

user.entity.ts

import { 
  Attribute, 
  Table, 
  VersionAttribute, 
  TModel, 
  TDynamoDbDocument 
} from 'nestjs-dynamodb';
import * as nanoid from 'nanoid';

export type UserPrimaryKey = { pk: string; sk: string }
export type UserModel = TModel<UserSchema, UserPrimaryKey>;
export type UserDocument = TDynamoDbDocument<UserEntity>;

@Table('users')
class UserEntity {
  @HashKey({ defaultProvider: nanoid })
  pk: string;

  @RangeKey()
  sk: string;

  @Attribute({
    type: 'Document',
    attributeName: '_p', // mapping name of field
    members: {
      name: {
        type: 'String'
      },
      age: {
        type: 'Number'
      }
    }
  })
  profile: {
    name: string;
    age: number;
  };

  @Attribute()
  createdAt: Date;

  @Attribute({ defaultProvider: () => new Date() })
  updatedAt: Date;

  // This property will not be saved to DynamoDB.
  notPersistedToDynamoDb: string;

  @VersionAttribute()
  __v: number;
}

users.service.ts

import { Injectable } from '@nestjs/common';
import { InjectModel } from 'nestjs-dynamodb';

import { UserModel, UserEntity, UserDocument, UserPrimaryKey } from './user.entity';

@Injectable()
export class UsersService {
  constructor(@InjectModel(UserEntity) private readonly userModel: UserModel) {}

  async find(pk: UserPrimaryKey): Promise<UserDocument> {
    return this.userModel.findByPrimaryKey(pk);
  }

  async create(input: UserInput): Promise<UserDocument> {
    return this.userModel.create(input);
  }

  async delete(pk: UserPrimaryKey): Promise<DynamoDB.DeleteItemOutput> {
    return this.userModel.delete(pk);
  }

  async update(pk: UserPrimaryKey, item: UserInput): Promise<UserDocument> {
    return this.userModel.update(pk, item);
  }
}