Skip to content

Commit

Permalink
Merge pull request #30 from otasoft/feat-#28/refactor-utils
Browse files Browse the repository at this point in the history
Feat #28/refactor utils
  • Loading branch information
Baroshem authored Feb 2, 2021
2 parents 8ff89ae + 4dfb806 commit 30f05ad
Show file tree
Hide file tree
Showing 25 changed files with 63 additions and 185 deletions.
1 change: 0 additions & 1 deletion src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@ This directory contains:
- `eventstore` -> Eventstore
- `health` -> Healthchecks
- `item` -> CQRS, Event Sourcing, DDD
- `utils` -> Rpc exception handling, Validating Database errors, service mocks
- AppModule -> Root module of the microservice application
- `main.ts` -> Root file of the Nest.js project
2 changes: 0 additions & 2 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { ConfigModule } from '@nestjs/config';

import { DatabaseModule } from './database/database.module';
import { HealthModule } from './health/health.module';
import { UtilsModule } from './utils/utils.module';
import { ItemModule } from './item/item.module';
import { EventStoreWrapperModule } from './event-store/event-store-wrapper.module';

Expand All @@ -12,7 +11,6 @@ import { EventStoreWrapperModule } from './event-store/event-store-wrapper.modul
ConfigModule.forRoot(),
DatabaseModule,
EventStoreWrapperModule,
UtilsModule,
HealthModule,
ItemModule,
],
Expand Down
1 change: 1 addition & 0 deletions src/database/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ This directory contains:

- DatabaseModule which is a wrapper for TypeOrmModule
- `config` directory with TypeOrmConfigService and index.ts exporting that service
- `helpers` directory with validateDbError method, error interface, and DbErrorCode enum
4 changes: 1 addition & 3 deletions src/database/config/type-orm-config.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Injectable } from '@nestjs/common';
import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from '@nestjs/typeorm';

import { ItemEntity } from '../../item/infrastructure/entities';

@Injectable()
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
createTypeOrmOptions(): TypeOrmModuleOptions {
Expand All @@ -14,7 +12,7 @@ export class TypeOrmConfigService implements TypeOrmOptionsFactory {
password: process.env.POSTGRES_PASSWORD,
database: process.env.POSTGRES_DATABASE,
synchronize: true,
entities: [ItemEntity],
autoLoadEntities: true,
};
}
}
1 change: 1 addition & 0 deletions src/database/helpers/enums/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './db-error-codes.enum';
2 changes: 2 additions & 0 deletions src/database/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './validate-db-error';
export * from './interfaces';
1 change: 1 addition & 0 deletions src/database/helpers/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './error-object.interface';
17 changes: 17 additions & 0 deletions src/database/helpers/validate-db-error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { DbErrorCodes } from './enums';
import { IErrorObject } from './interfaces';

/**
* A method that returns a correct HTTP exception object based on the database error code provided as a parameter
*
* @param {string} errorCode
* @return {*} {IErrorObject}
*/
export const validateDbError = (errorCode: string): IErrorObject => {
switch (errorCode) {
case DbErrorCodes.UniqueViolation:
return { code: 409, message: 'Duplicated entry' };
default:
return { code: 400, message: 'Bad Request' };
}
};
11 changes: 4 additions & 7 deletions src/item/application/commands/handlers/create-item.handler.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { CommandHandler, EventPublisher, ICommandHandler } from '@nestjs/cqrs';
import { InjectRepository } from '@nestjs/typeorm';
import { RpcException } from '@nestjs/microservices';

import { ErrorValidationService, RpcExceptionService } from '../../../../utils';
import { ItemEntity } from '../../../infrastructure/entities';
import { ItemRepository } from '../../../domain/repositories';
import { ItemWriteRepository } from '../../../infrastructure/repositories';
import { CreateItemCommand } from '../impl';
import { validateDbError } from '../../../../database/helpers';

@CommandHandler(CreateItemCommand)
export class CreateItemHandler implements ICommandHandler<CreateItemCommand> {
Expand All @@ -14,8 +15,6 @@ export class CreateItemHandler implements ICommandHandler<CreateItemCommand> {
private readonly itemWriteRepository: ItemWriteRepository,
private readonly itemRepository: ItemRepository,
private readonly publisher: EventPublisher,
private readonly rpcExceptionService: RpcExceptionService,
private readonly errorValidationService: ErrorValidationService,
) {}

async execute(command: CreateItemCommand): Promise<ItemEntity> {
Expand All @@ -36,11 +35,9 @@ export class CreateItemHandler implements ICommandHandler<CreateItemCommand> {

return item;
} catch (error) {
const errorObject = this.errorValidationService.validateDbError(
error.code,
);
const { code, message } = validateDbError(error.code);

this.rpcExceptionService.throwCatchedException(errorObject);
throw new RpcException({ statusCode: code, errorStatus: message });
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { CommandHandler, EventPublisher, ICommandHandler } from '@nestjs/cqrs';
import { InjectRepository } from '@nestjs/typeorm';
import { RpcException } from '@nestjs/microservices';

import { DeleteItemByIdCommand } from '../impl';
import { RpcExceptionService, ErrorValidationService } from '../../../../utils';
import { ItemEntity } from '../../../infrastructure/entities';
import { ItemRepository } from '../../../domain/repositories';
import { ItemWriteRepository } from '../../../infrastructure/repositories';
import { validateDbError } from '../../../../database/helpers';

@CommandHandler(DeleteItemByIdCommand)
export class DeleteItemByIdHandler
Expand All @@ -15,17 +16,16 @@ export class DeleteItemByIdHandler
private readonly itemWriteRepository: ItemWriteRepository,
private readonly itemRepository: ItemRepository,
private readonly publisher: EventPublisher,
private readonly rpcExceptionService: RpcExceptionService,
private readonly errorValidationService: ErrorValidationService,
) {}

async execute(command: DeleteItemByIdCommand): Promise<ItemEntity> {
const item = await this.itemWriteRepository.findOne(command.id);

if (!item)
this.rpcExceptionService.throwNotFound(
'Cannot delete item because the item was not found',
);
throw new RpcException({
statusCode: 404,
errorStatus: 'Cannot delete item because the item was not found',
});

try {
await this.itemWriteRepository.delete(item);
Expand All @@ -37,11 +37,9 @@ export class DeleteItemByIdHandler

return item;
} catch (error) {
const errorObject = this.errorValidationService.validateDbError(
error.code,
);
const { code, message } = validateDbError(error.code);

this.rpcExceptionService.throwCatchedException(errorObject);
throw new RpcException({ statusCode: code, errorStatus: message });
}
}
}
17 changes: 9 additions & 8 deletions src/item/application/commands/handlers/update-item.handler.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { CommandHandler, EventPublisher, ICommandHandler } from '@nestjs/cqrs';
import { InjectRepository } from '@nestjs/typeorm';
import { RpcException } from '@nestjs/microservices';

import { UpdateItemCommand } from '../impl';
import { RpcExceptionService, ErrorValidationService } from '../../../../utils';
import { ItemEntity } from '../../../infrastructure/entities';
import { ItemRepository } from '../../../domain/repositories';
import { ItemWriteRepository } from '../../../infrastructure/repositories';
import { validateDbError } from '../../../../database/helpers';

@CommandHandler(UpdateItemCommand)
export class UpdateItemHandler implements ICommandHandler<UpdateItemCommand> {
Expand All @@ -14,16 +15,18 @@ export class UpdateItemHandler implements ICommandHandler<UpdateItemCommand> {
private readonly itemWriteRepository: ItemWriteRepository,
private readonly itemRepository: ItemRepository,
private readonly publisher: EventPublisher,
private readonly rpcExceptionService: RpcExceptionService,
private readonly errorValidationService: ErrorValidationService,
) {}

async execute(command: UpdateItemCommand): Promise<ItemEntity> {
const { updateItemDto } = command;

const item = await this.itemWriteRepository.findOne(updateItemDto.id);

if (!item) this.rpcExceptionService.throwNotFound('Item not found');
if (!item)
throw new RpcException({
statusCode: 404,
errorStatus: 'Item not found',
});

item.name = updateItemDto.name;

Expand All @@ -38,11 +41,9 @@ export class UpdateItemHandler implements ICommandHandler<UpdateItemCommand> {

return item;
} catch (error) {
const errorObject = this.errorValidationService.validateDbError(
error.code,
);
const { code, message } = validateDbError(error.code);

this.rpcExceptionService.throwCatchedException(errorObject);
throw new RpcException({ statusCode: code, errorStatus: message });
}
}
}
12 changes: 8 additions & 4 deletions src/item/application/queries/handlers/get-item-by-id.handler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { QueryHandler, IQueryHandler } from '@nestjs/cqrs';
import { InjectRepository } from '@nestjs/typeorm';
import { RpcException } from '@nestjs/microservices';

import { RpcExceptionService } from '../../../../utils/exception-handling';
import { GetItemByIdQuery } from '../impl';
import { ItemEntity } from '../../../infrastructure/entities';
import { ItemReadRepository } from '../../../infrastructure/repositories';
Expand All @@ -11,13 +11,17 @@ export class GetItemByIdHandler implements IQueryHandler<GetItemByIdQuery> {
constructor(
@InjectRepository(ItemReadRepository)
private readonly itemReadRepository: ItemReadRepository,
private readonly rpcExceptionService: RpcExceptionService,
) {}

async execute(query: GetItemByIdQuery): Promise<ItemEntity> {
const item = await this.itemReadRepository.findOne(query.id);
const { id } = query;
const item = await this.itemReadRepository.findOne(id);

if (!item) this.rpcExceptionService.throwNotFound('Item not found');
if (!item)
throw new RpcException({
statusCode: 404,
errorStatus: `Item with ID: ${id} not found`,
});

return item;
}
Expand Down
8 changes: 5 additions & 3 deletions src/item/application/queries/handlers/get-items.handler.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { IQueryHandler, QueryHandler } from '@nestjs/cqrs';
import { InjectRepository } from '@nestjs/typeorm';
import { RpcException } from '@nestjs/microservices';

import { ItemEntity } from '../../../infrastructure/entities';
import { ItemReadRepository } from '../../../infrastructure/repositories';
import { RpcExceptionService } from '../../../../utils';
import { GetItemsQuery } from '../impl';

@QueryHandler(GetItemsQuery)
export class GetItemsHandler implements IQueryHandler<GetItemsQuery> {
constructor(
@InjectRepository(ItemReadRepository)
private readonly itemReadRepository: ItemReadRepository,
private readonly rpcExceptionService: RpcExceptionService,
) {}

async execute(query: GetItemsQuery): Promise<ItemEntity[]> {
Expand All @@ -20,7 +19,10 @@ export class GetItemsHandler implements IQueryHandler<GetItemsQuery> {
const items = await this.itemReadRepository.find({ take: limit });

if (!items.length)
this.rpcExceptionService.throwNotFound('Items not found');
throw new RpcException({
statusCode: 404,
errorStatus: 'Items not found',
});

return items;
}
Expand Down
7 changes: 6 additions & 1 deletion src/item/infrastructure/infrastructure.module.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { Global, Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

import { ItemEntity } from './entities';
import { ItemReadRepository, ItemWriteRepository } from './repositories';

@Global()
@Module({
imports: [
TypeOrmModule.forFeature([ItemReadRepository, ItemWriteRepository]),
TypeOrmModule.forFeature([
ItemReadRepository,
ItemWriteRepository,
ItemEntity,
]),
],
})
export class InfrastructureModule {}
14 changes: 0 additions & 14 deletions src/utils/README.md

This file was deleted.

22 changes: 0 additions & 22 deletions src/utils/error-validation/error-validation.service.ts

This file was deleted.

2 changes: 0 additions & 2 deletions src/utils/error-validation/index.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/utils/exception-handling/index.ts

This file was deleted.

Loading

0 comments on commit 30f05ad

Please sign in to comment.