create/edit/delete Dish

김종민·2022년 7월 4일
0

Nuber-Server

목록 보기
25/34


들어가기
Dish를 create 및 edit 하는 API

1. dtos

1-1.create-dish.dto.ts

import { Field, InputType, Int, ObjectType, PickType } from '@nestjs/graphql';
import { MutationOutput } from 'src/common/dtos/output.dto';
import { Dish } from '../entities/dish.entity';

@InputType()
export class CreateDishInput extends PickType(Dish, [
  'name',
  'price',
  'options',
  'description',
]) {
  @Field(() => Int)
  restaurantId: number;
}
///PickType으로 하고 restaurantId를 추가로 Field()에 넣는다.

@ObjectType()
export class CreateDishOutput extends MutationOutput {}

1-2.edit-dish.dto.ts

import {
  Field,
  InputType,
  Int,
  ObjectType,
  PartialType,
  PickType,
} from '@nestjs/graphql';
import { MutationOutput } from 'src/common/dtos/output.dto';
import { Dish } from '../entities/dish.entity';

@InputType()
export class EditDishInput extends PickType(PartialType(Dish), [
  'name',
  'options',
  'price',
  'description',
]) {
  @Field(() => Int)
  dishId: number;
}
///edit이기 때문에, Picktype과 PartialType을 같이 쓴다.

@ObjectType()
export class EditDishOutput extends MutationOutput {}

1-3.delete-dish.dto.ts

import { Field, InputType, Int, ObjectType } from '@nestjs/graphql';
import { MutationOutput } from 'src/common/dtos/output.dto';

@InputType()
export class DeleteDishInput {
  @Field(() => Int)
  dishId: number;
}
///dishId만 'input'으로 받는다.

@ObjectType()
export class DeleteDishOutput extends MutationOutput {}

2. Resolver

@Resolver(() => Dish)
export class DishResolver {
  constructor(private readonly restaurantService: RestaurantService) {}

  @Mutation(() => CreateDishOutput)
  @Role(['Owner'])
  createDish(
    @AuthUser() owner: User,
    @Args('input') createDishInput: CreateDishInput,
  ): Promise<CreateDishOutput> {
    return this.restaurantService.createDish(owner, createDishInput);
  }

  @Mutation(() => EditDishOutput)
  @Role(['Owner'])
  editDish(
    @AuthUser() owner: User,
    @Args('input') editDishInput: EditDishInput,
  ): Promise<EditDishOutput> {
    return this.restaurantService.editDish(owner, editDishInput);
  }

  @Mutation(() => DeleteDishOutput)
  @Role(['Owner'])
  deleteDish(
    @AuthUser() owner: User,
    @Args('input') deleteDishInput: DeleteDishInput,
  ): Promise<EditDishOutput> {
    return this.restaurantService.deleteDish(owner, deleteDishInput);
  }
  
  ///셋다 Role설정하고, AuthUser설정하고, dto넣어준다.

3. service

  async createDish(
    owner: User,
    createDishInput: CreateDishInput,
  ): Promise<CreateDishOutput> {
    try {
      const restaurant = await this.restaurants.findOne(
        createDishInput.restaurantId,
      );
      ///restaurantId 받아서, restaurant찾음.
      
      if (!restaurant) {
        return {
          ok: false,
          error: 'Restaurant not found',
        };
      }
      if (owner.id !== restaurant.ownerId) {
        return {
          ok: false,
          error: 'You can not do that!!',
        };
      }
      ///loggedInUser와 restaurant.ownerId가 동일해야 Dish만들기 가능
      
      await this.dishes.save(
        this.dishes.create({ ...createDishInput, restaurant }),
      );
      ///반드시 create에서 restaurant를 같이 넣어주어야 한다.
      ///그래야 Dish DB에 restaurantId가 같이 찍힘.

      return {
        ok: true,
      };
    } catch (error) {
      console.log(error);
      return {
        ok: false,
        error: 'Could not create Dish!!',
      };
    }
  }

  async editDish(
    owner: User,
    editDishInput: EditDishInput,
  ): Promise<EditDishOutput> {
    try {
      const dish = await this.dishes.findOne(editDishInput.dishId, {
        relations: ['restaurant'],
      });
      ///edit할 dish를 찾아주는데 반드시, relations로 restaurant를 같이 불러준다.
      
      if (!dish) {
        return {
          ok: false,
          error: 'Dish not fouund',
        };
      }
      if (dish.restaurant.ownerId !== owner.id) {
        return {
          ok: false,
          error: 'You can not do that!!',
        };
      }
      await this.dishes.save([
        {
          id: editDishInput.dishId,
          ...editDishInput,
        },
      ]);
      ///edit에서 update되는 것은,save로, ...editDishInput으로.
      ///id는 editDishInput.dishId임
      
      return {
        ok: true,
      };
    } catch {
      return {
        ok: false,
        error: 'Could not delete Dish',
      };
    }
  }

  async deleteDish(
    owner: User,
    { dishId }: DeleteDishInput,
  ): Promise<DeleteDishOutput> {
    try {
      const dish = await this.dishes.findOne(dishId, {
        relations: ['restaurant'],
      });
      ///dish를 찾을떈, 반드시, relations로 'restaurant'를 갑이 찾아준다.
      
      if (!dish) {
        return {
          ok: false,
          error: 'Dish not found',
        };
      }
      if (dish.restaurant.ownerId !== owner.id) {
        return {
          ok: false,
          error: 'You can not do that',
        };
      }
      await this.dishes.delete(dishId);
      ///delete명령은 매우 간단함. dishId만 넣어주면 됨.
      
      return {
        ok: true,
      };
    } catch {
      return {
        ok: false,
        error: 'Can not delete',
      };
    }
  }
  

createDish, editDish, deleteDish 세개는 비슷하니까 비교해 가면서 본다.
relations:['restaurant'] 부분과, {...editDishInut}. {...createDishInput}등,
점세개 찍히는 부분 ...을 유심히 본다.

profile
코딩하는초딩쌤

0개의 댓글