Skip to content

emanuelfs/nest-shopping-list

Repository files navigation

Nest Logo

A progressive Node.js framework for building efficient and scalable server-side applications.

NPM Version Package License NPM Downloads CircleCI Coverage Discord Backers on Open Collective Sponsors on Open Collective Support us

Description

Nest framework TypeScript starter repository.

Installation

$ npm install

Running the app

# development
$ npm run start

# watch mode
$ npm run start:dev

# production mode
$ npm run start:prod

Test

# unit tests
$ npm run test

# e2e tests
$ npm run test:e2e

# test coverage
$ npm run test:cov

Help

npm install -g @nestjs/cli
nest new nest-shopping-list
cd nest-shopping-list
npm install --save @nestjs/typeorm typeorm mysql2 @nestjs/config class-validator class-transformer @nestjs/swagger swagger-ui-express
nest generate resource item

File ".env"

SERVER_PORT=3000
MODE=DEV
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USERNAME=meet_pet_dbo
DB_PASSWORD=P@ssw0rd
DB_DATABASE=meet_pet
DB_SYNCHRONIZE=true

File "src/app.module.ts"

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config'; //add this line
import { TypeOrmModule } from '@nestjs/typeorm'; //add this line
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ItemModule } from './item/item.module';

@Module({
  imports: [
    ConfigModule.forRoot(), //add this line
    TypeOrmModule.forRoot({ //add this block
      type: 'mysql',
      host: process.env.DB_HOST,
      port: parseInt(process.env.DB_PORT),
      username: process.env.DB_USERNAME,
      password: process.env.DB_PASSWORD,
      database: process.env.DB_DATABASE,
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: (process.env.DB_SYNCHRONIZE === 'true'),
    }),
    ItemModule
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule { }

File "src/item/entities/item.entity.ts"

import { BaseEntity, Column, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";  //add this line

@Entity() //add this line
export class Item extends BaseEntity { //add this block
    @PrimaryGeneratedColumn('uuid')
    id: string;

    @UpdateDateColumn({ name: 'updated_at', type: 'timestamp' })
    updatedAt: Date;

    @Column({ name: 'name', type: 'varchar', length: 50 })
    name: string;

    @Column({ name: 'description', type: 'varchar', nullable: true, length: 255 })
    description?: string;

    @Column({ name: 'quantity', type: 'int' })
    quantity: number;
}

File "src/item/dto/create-item.dto.ts"

import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';  //add this line
import { IsInt, IsNotEmpty, IsOptional, IsString, Min } from 'class-validator';  //add this line

export class CreateItemDto { //add this block
    @ApiProperty({ example: 'Bananas' })
    @IsString()
    @IsNotEmpty()
    name: string;

    @ApiPropertyOptional({ example: 'Cavendish bananas', description: 'Optional description of the item' })
    @IsOptional()
    @IsString()
    description: string;

    @ApiProperty({ example: 5, description: 'Needed quantity' })
    @IsInt()
    @Min(0)
    quantity: number;
}

File "src/main.ts"

import { ValidationPipe } from '@nestjs/common'; //add this line
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; //add this line
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  app.useGlobalPipes(new ValidationPipe()); //add this line

  const config = new DocumentBuilder() //add this line
    .setTitle('Shopping list API') //add this line
    .setDescription('My shopping list API description') //add this line
    .setVersion('1.0') //add this line
    .build(); //add this line

  SwaggerModule.setup('api', app, SwaggerModule.createDocument(app, config)); //add this line

  await app.listen(3000);
}

bootstrap();

File "src/item/item.service.ts"

import { Injectable, NotFoundException } from '@nestjs/common'; //edit this line
import { InjectRepository } from '@nestjs/typeorm'; //add this line
import { Repository } from 'typeorm'; //add this line
import { CreateItemDto } from './dto/create-item.dto';
import { UpdateItemDto } from './dto/update-item.dto';
import { Item } from './entities/item.entity'; //add this line

@Injectable()
export class ItemService {
  constructor(@InjectRepository(Item) private readonly repository: Repository<Item>) { } //add this line

  create(createItemDto: CreateItemDto): Promise<Item> { //edit this line
    const item = this.repository.create(createItemDto); //add this line
    return this.repository.save(item); //edit this line
  }

  findAll(): Promise<Item[]> { //edit this line
    return this.repository.find(); //edit this line
  }

  findOne(id: string): Promise<Item> { //edit this line
    return this.repository.findOne(id); //edit this line
  }

  async update(id: string, updateItemDto: UpdateItemDto): Promise<Item> { //edit this line
    const item = await this.repository.preload({ //add this line
      id: id, //add this line
      ...updateItemDto, //add this line
    }); //add this line
    if (!item) { //add this line
      throw new NotFoundException(`Item ${id} not found`); //add this line
    } //add this line
    return this.repository.save(item); //edit this line
  }

  async remove(id: string) { //edit this line
    const item = await this.findOne(id); //add this line
    return this.repository.remove(item); //edit this line
  }
}

File "src/item/item.module.ts"

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm'; //add this line
import { Item } from './entities/item.entity'; //add this line
import { ItemService } from './item.service';
import { ItemController } from './item.controller';

@Module({
  imports: [TypeOrmModule.forFeature([Item])], //add this line
  controllers: [ItemController],
  providers: [ItemService]
})
export class ItemModule { }

File "src/item/item.controller.ts"

import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
import { ItemService } from './item.service';
import { CreateItemDto } from './dto/create-item.dto';
import { UpdateItemDto } from './dto/update-item.dto';

@Controller('item')
export class ItemController {
  constructor(private readonly itemService: ItemService) {}

  @Post()
  create(@Body() createItemDto: CreateItemDto) {
    return this.itemService.create(createItemDto);
  }

  @Get()
  findAll() {
    return this.itemService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.itemService.findOne(id); //edit this line
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateItemDto: UpdateItemDto) {
    return this.itemService.update(id, updateItemDto); //edit this line
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.itemService.remove(id); //edit this line
  }
}

Reference: https://www.sidechannel.blog/en/creating-an-api-with-nestjs/index.html

Support

Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.

Stay in touch

License

Nest is MIT licensed.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published