Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/hardyscc/nestjs-dynamoose
Dynamoose module for Nest
https://github.com/hardyscc/nestjs-dynamoose
dynamodb dynamoose nest nestjs
Last synced: 1 day ago
JSON representation
Dynamoose module for Nest
- Host: GitHub
- URL: https://github.com/hardyscc/nestjs-dynamoose
- Owner: hardyscc
- License: mit
- Created: 2020-03-20T07:54:53.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2024-12-14T06:29:52.000Z (8 days ago)
- Last Synced: 2024-12-14T09:05:12.563Z (8 days ago)
- Topics: dynamodb, dynamoose, nest, nestjs
- Language: TypeScript
- Homepage:
- Size: 3.42 MB
- Stars: 142
- Watchers: 2
- Forks: 24
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
A progressive Node.js framework for building efficient and scalable server-side applications.
## Description
[Dynamoose](https://dynamoosejs.com/) module for [Nest](https://github.com/nestjs/nest).
## Installation
```bash
$ npm install --save nestjs-dynamoose dynamoose
```## Example Project
A [AWS NestJS Starter](https://github.com/hardyscc/aws-nestjs-starter) project has been created to demo the usage of this library.
## Quick Start
**1. Add import into your app module**
`src/app.module.ts`
```ts
import { DynamooseModule } from 'nestjs-dynamoose';
import { UserModule } from './user/user.module';@Module({
imports: [
DynamooseModule.forRoot(),
UserModule,
],
})
export class AppModule {
````forRoot()` optionally accepts the following options defined by `DynamooseModuleOptions`:
```ts
interface DynamooseModuleOptions {
aws?: {
accessKeyId?: string;
secretAccessKey?: string;
region?: string;
};
local?: boolean | string;
ddb?: DynamoDB;
table?: TableOptionsOptional;
logger?: boolean | LoggerService;
}
```There is also `forRootAsync(options: DynamooseModuleAsyncOptions)` if you want to use a factory with dependency injection.
**2. Create a schema**
`src/user/user.schema.ts`
```ts
import { Schema } from 'dynamoose';export const UserSchema = new Schema({
id: {
type: String,
hashKey: true,
},
name: {
type: String,
},
email: {
type: String,
},
});
````src/user/user.interface.ts`
```ts
export interface UserKey {
id: string;
}export interface User extends UserKey {
name: string;
email?: string;
}
````UserKey` holds the hashKey/partition key and (optionally) the rangeKey/sort key. `User` holds all attributes of the document/item. When creating this two interfaces and using when injecting your model you will have typechecking when using operations like `Model.update()`.
**3. Add the models you want to inject to your modules**
This can be a feature module (as shown below) or within the root AppModule next to `DynamooseModule.forRoot()`.
`src/user/user.module.ts`
```ts
import { DynamooseModule } from 'nestjs-dynamoose';
import { UserSchema } from './user.schema';
import { UserService } from './user.service';@Module({
imports: [
DynamooseModule.forFeature([{
name: 'User',
schema: UserSchema,
options: {
tableName: 'user',
},
}]),
],
providers: [
UserService,
...
],
})
export class UserModule {}
```> `options.tableName` is optional. If it is not provided, `name` will be used as the table name.
There is also `forFeatureAsync(factories?: AsyncModelFactory[])` if you want to use a factory with dependency injection. Notes that the first parameter of the `useFactory` callback is reserved for future use, so please just add `_,` to ignore it.
The following example will use `USER_TABLE_NAME` environment variable as the table name.
```ts
import { DynamooseModule } from 'nestjs-dynamoose';
import { UserSchema } from './user.schema';
import { UserService } from './user.service';@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
DynamooseModule.forFeatureAsync([
{
name: 'User',
useFactory: (_, configService: ConfigService) => {
return {
schema: UserSchema,
options: {
tableName: configService.get('USER_TABLE_NAME'),
},
};
},
inject: [ConfigService],
},
]),
],
providers: [
UserService,
...
],
})
export class UserModule {}
```**4. Inject and use your model**
`src/user/user.service.ts`
```ts
import { Injectable } from '@nestjs/common';
import { InjectModel, Model } from 'nestjs-dynamoose';
import { User, UserKey } from './user.interface';@Injectable()
export class UserService {
constructor(
@InjectModel('User')
private userModel: Model,
) {}create(user: User) {
return this.userModel.create(user);
}update(key: UserKey, user: Partial) {
return this.userModel.update(key, user);
}findOne(key: UserKey) {
return this.userModel.get(key);
}findAll() {
return this.userModel.scan().exec();
}
}
```## Additional Example
**1. Transaction Support**
Both `User` and `Account` model objects will commit in same transaction.
```ts
import { Injectable } from '@nestjs/common';
import { InjectModel, Model, TransactionSupport } from 'nestjs-dynamoose';
import { User, UserKey } from './user.interface';
import { Account, AccountKey } from './account.interface';@Injectable()
export class UserService extends TransactionSupport {
constructor(
@InjectModel('User')
private userModel: Model,
@InjectModel('Account')
private accountModel: Model,
) {
super();
}async create(user: User, account: Account) {
await this.transaction([
this.userModel.transaction.create(user),
this.accountModel.transaction.create(account),
]);
}
}
```**2. Serializers Support**
Define the additional `serializers` under `DynamooseModule.forFeature()`.
```ts
@Module({
imports: [
DynamooseModule.forFeature([
{
name: 'User',
schema: UserSchema,
serializers: {
frontend: { exclude: ['status'] },
},
},
]),
],
...
})
export class UserModule {}
```Call the `serialize` function to exclude the `status` field.
```ts
@Injectable()
export class UserService {
...
async create(user: User) {
const createdUser = await this.userModel.create(user);
return createdUser.serialize('frontend');
}
...
}
```## License
Dynamoose module for Nest is [MIT licensed](LICENSE).