diff --git a/nestjs/src/app.module.ts b/nestjs/src/app.module.ts index ea4b424..f3b5a97 100644 --- a/nestjs/src/app.module.ts +++ b/nestjs/src/app.module.ts @@ -1,13 +1,24 @@ -import { Module } from '@nestjs/common'; +import { Module, MiddlewareConsumer, RequestMethod } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; -import { CatsController } from './cats/cats.controller'; -import { CatsService } from './cats/cats.service'; import { CatsModule } from './cats/cats.module'; - +import { logger } from './common/middleware/logger.middleware'; +import { CatsController } from './cats/cats.controller'; +import { MongooseModule } from '@nestjs/mongoose'; +import { TodoModule } from './todo/todo.module'; @Module({ - imports: [CatsModule], + imports: [CatsModule, MongooseModule.forRoot('mongodb://localhost/nest'), TodoModule], controllers: [AppController], providers: [AppService], }) -export class AppModule {} +export class AppModule { + configure(consumer: MiddlewareConsumer) { + consumer + .apply(logger) + .exclude( + { path: 'cats', method: RequestMethod.GET }, + { path: 'cats', method: RequestMethod.POST }, + ) + .forRoutes(CatsController); + } +} diff --git a/nestjs/src/cats/cats.controller.ts b/nestjs/src/cats/cats.controller.ts index 29a7a15..be27e87 100644 --- a/nestjs/src/cats/cats.controller.ts +++ b/nestjs/src/cats/cats.controller.ts @@ -6,12 +6,17 @@ import { Post, Body, HttpStatus, + HttpException, + ForbiddenException, + Param, + ParseIntPipe, } from '@nestjs/common'; -import { Request } from 'express'; import { CatsService } from './cats.service'; import { CreateCatDto } from './create-cat.dto'; import { Cat } from 'src/interfaces/cat.interface'; +import { Query } from '@nestjs/common/decorators'; +import { UsePipes } from '@nestjs/common/decorators/core/use-pipes.decorator'; @Controller('cats') export class CatsController { @@ -21,8 +26,40 @@ export class CatsController { this.catsService.create(createCatDto); } - @Get() - async findAll(): Promise { + @Get(':id') + async findOne( + @Param( + 'id', + new ParseIntPipe({ errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE }), + ) + id: number, + ) { return this.catsService.findAll(); } + // @Get() + // async xxx() { + // try { + // await this.catsService.findAll(); + // } catch (error) { + // throw new HttpException( + // { + // status: HttpStatus.FORBIDDEN, + // error: 'This is a custom message', + // }, + // HttpStatus.FORBIDDEN, + // { + // cause: error, + // }, + // ); + // } + // } + // @Get() + // async findAll() { + // throw new ForbiddenException(); + // } + + // @Get() + // async findAll(): Promise { + // return this.catsService.findAll(); + // } } diff --git a/nestjs/src/cats/cats.module.ts b/nestjs/src/cats/cats.module.ts index 90dee6a..862e134 100644 --- a/nestjs/src/cats/cats.module.ts +++ b/nestjs/src/cats/cats.module.ts @@ -1,8 +1,18 @@ import { Module } from '@nestjs/common'; import { CatsController } from './cats.controller'; import { CatsService } from './cats.service'; +import { MongooseModule } from '@nestjs/mongoose'; +import { Cat, CatSchema } from 'src/schemas/cat.schema'; @Module({ + imports: [ + MongooseModule.forFeature([ + { + name: Cat.name, + schema: CatSchema, + }, + ]), + ], controllers: [CatsController], providers: [CatsService], }) diff --git a/nestjs/src/cats/cats.service.ts b/nestjs/src/cats/cats.service.ts index c33aa92..2c2cc95 100644 --- a/nestjs/src/cats/cats.service.ts +++ b/nestjs/src/cats/cats.service.ts @@ -1,13 +1,14 @@ import { Injectable } from '@nestjs/common'; -import { Cat } from 'src/interfaces/cat.interface'; +// import { Cat } from 'src/interfaces/cat.interface'; +import { InjectModel } from '@nestjs/mongoose'; +import { Model } from 'mongoose'; +import { Cat, CatDocument } from 'src/schemas/cat.schema'; +import { CreateCatDto } from './create-cat.dto'; @Injectable() export class CatsService { private readonly cats: Cat[] = []; - - create(cat: Cat) { - this.cats.push(cat); - } + async create(createCatDto: CreateCatDto) {} findAll(): Cat[] { return this.cats; diff --git a/nestjs/src/cats/create-cat.dto.ts b/nestjs/src/cats/create-cat.dto.ts index 492e2d9..8d4d715 100644 --- a/nestjs/src/cats/create-cat.dto.ts +++ b/nestjs/src/cats/create-cat.dto.ts @@ -1,5 +1,10 @@ +import { IsString, IsInt } from 'class-validator'; + export class CreateCatDto { + @IsString() name: string; + @IsInt() age: number; + @IsString() breed: string; } diff --git a/nestjs/src/cats/forbidden.exception.ts b/nestjs/src/cats/forbidden.exception.ts new file mode 100644 index 0000000..a189549 --- /dev/null +++ b/nestjs/src/cats/forbidden.exception.ts @@ -0,0 +1,7 @@ +import { HttpStatus, HttpException } from '@nestjs/common'; + +export class ForbiddenException extends HttpException { + constructor() { + super('Forbidden', HttpStatus.FORBIDDEN); + } +} diff --git a/nestjs/src/common/middleware/logger.middleware.ts b/nestjs/src/common/middleware/logger.middleware.ts new file mode 100644 index 0000000..8c01b66 --- /dev/null +++ b/nestjs/src/common/middleware/logger.middleware.ts @@ -0,0 +1,6 @@ +import { Request, Response, NextFunction } from 'express'; + +export function logger(req: Request, res: Response, next: NextFunction) { + console.log(`Request...`); + next(); +} diff --git a/nestjs/src/schemas/cat.schema.ts b/nestjs/src/schemas/cat.schema.ts new file mode 100644 index 0000000..e0b2f0b --- /dev/null +++ b/nestjs/src/schemas/cat.schema.ts @@ -0,0 +1,16 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { HydratedDocument } from 'mongoose'; + +export type CatDocument = HydratedDocument; + +@Schema() +export class Cat { + @Prop() + name: string; + @Prop() + age: number; + @Prop() + breed: string; +} + +export const CatSchema = SchemaFactory.createForClass(Cat); diff --git a/nestjs/src/todo/dto/base-todo.dto.ts b/nestjs/src/todo/dto/base-todo.dto.ts new file mode 100644 index 0000000..41ea56e --- /dev/null +++ b/nestjs/src/todo/dto/base-todo.dto.ts @@ -0,0 +1,4 @@ +export class BaseTodoDto { + title: string; + description?: string; +} diff --git a/nestjs/src/todo/dto/create-todo.dto.ts b/nestjs/src/todo/dto/create-todo.dto.ts new file mode 100644 index 0000000..3fdb352 --- /dev/null +++ b/nestjs/src/todo/dto/create-todo.dto.ts @@ -0,0 +1,3 @@ +import { BaseTodoDto } from './base-todo.dto'; + +export class CreateTodoDto extends BaseTodoDto {} diff --git a/nestjs/src/todo/dto/update-todo.dto.ts b/nestjs/src/todo/dto/update-todo.dto.ts new file mode 100644 index 0000000..e4d0915 --- /dev/null +++ b/nestjs/src/todo/dto/update-todo.dto.ts @@ -0,0 +1,5 @@ +import { BaseTodoDto } from './base-todo.dto'; + +export class UpdateTodoDto extends BaseTodoDto { + completedAt: Date; +} diff --git a/nestjs/src/todo/schemas/schema.ts b/nestjs/src/todo/schemas/schema.ts new file mode 100644 index 0000000..50d019c --- /dev/null +++ b/nestjs/src/todo/schemas/schema.ts @@ -0,0 +1,20 @@ +import { Document } from 'mongoose'; +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; + +export type TodoDocument = Todo & Document; + +@Schema() +export class Todo { + @Prop({ required: true }) + title: string; + @Prop() + description?: string; + @Prop() + completeAt?: Date; + @Prop() + createAt: Date; + @Prop() + deleteAt?: Date; +} + +export const TodoSchema = SchemaFactory.createForClass(Todo); diff --git a/nestjs/src/todo/todo.controller.spec.ts b/nestjs/src/todo/todo.controller.spec.ts new file mode 100644 index 0000000..1925914 --- /dev/null +++ b/nestjs/src/todo/todo.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { TodoController } from './todo.controller'; + +describe('TodoController', () => { + let controller: TodoController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [TodoController], + }).compile(); + + controller = module.get(TodoController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/nestjs/src/todo/todo.controller.ts b/nestjs/src/todo/todo.controller.ts new file mode 100644 index 0000000..b18620f --- /dev/null +++ b/nestjs/src/todo/todo.controller.ts @@ -0,0 +1,37 @@ +import { + Post, + Controller, + Body, + Put, + Delete, + Get, + Param, +} from '@nestjs/common'; +import { UpdateTodoDto } from './dto/update-todo.dto'; +import { CreateTodoDto } from './dto/create-todo.dto'; +import { TodoService } from './todo.service'; + +@Controller('todo') +export class TodoController { + constructor(private readonly service: TodoService) {} + @Get() + async index() { + return await this.service.findAll(); + } + @Get(':id') + async find(@Param('id') id: string) { + return await this.service.findOne(id); + } + @Post() + async create(@Body() createTodoDto: CreateTodoDto) { + return await this.service.create(createTodoDto); + } + @Put(':id') + async update(@Param('id') id: string, @Body() UpdateTodoDto: UpdateTodoDto) { + return await this.service.update(id, UpdateTodoDto); + } + @Delete(':id') + async delete(@Param('id') id: string) { + return await this.service.delete(id); + } +} diff --git a/nestjs/src/todo/todo.module.ts b/nestjs/src/todo/todo.module.ts new file mode 100644 index 0000000..247a4e8 --- /dev/null +++ b/nestjs/src/todo/todo.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { TodoService } from './todo.service'; +import { TodoController } from './todo.controller'; +import { Mongoose } from 'mongoose'; +import { MongooseModule, Schema } from '@nestjs/mongoose'; +import { TodoSchema, Todo } from './schemas/schema'; + +@Module({ + providers: [TodoService], + controllers: [TodoController], + imports: [ + MongooseModule.forFeature([{ name: Todo.name, schema: TodoSchema }]), + ], +}) +export class TodoModule {} diff --git a/nestjs/src/todo/todo.service.spec.ts b/nestjs/src/todo/todo.service.spec.ts new file mode 100644 index 0000000..50097b7 --- /dev/null +++ b/nestjs/src/todo/todo.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { TodoService } from './todo.service'; + +describe('TodoService', () => { + let service: TodoService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [TodoService], + }).compile(); + + service = module.get(TodoService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/nestjs/src/todo/todo.service.ts b/nestjs/src/todo/todo.service.ts new file mode 100644 index 0000000..07c3fa4 --- /dev/null +++ b/nestjs/src/todo/todo.service.ts @@ -0,0 +1,36 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { Model } from 'mongoose'; +import { Todo, TodoDocument } from './schemas/schema'; +import { CreateTodoDto } from './dto/create-todo.dto'; +import { UpdateTodoDto } from './dto/update-todo.dto'; + +@Injectable() +export class TodoService { + constructor( + @InjectModel(Todo.name) private readonly model: Model, + ) {} + + async findAll(): Promise { + return await this.model.find().exec(); + } + + async findOne(id: string): Promise { + return await this.model.findById(id).exec(); + } + + async create(createTodoDto: CreateTodoDto): Promise { + return await new this.model({ + ...createTodoDto, + createdAt: new Date(), + }).save(); + } + + async update(id: string, updateToDto: UpdateTodoDto): Promise { + return await this.model.findByIdAndUpdate(id, updateToDto).exec(); + } + + async delete(id: string): Promise { + return await this.model.findByIdAndDelete(id).exec(); + } +}