see AllCategory, category, pagination

김종민·2022년 7월 2일
0

Nuber-Server

목록 보기
21/34


들어가기
모든 카테고리(한식, 일식등등)를 보고,
카테고리에 딸린 식당 및, 식당 갯수등을
보는 API
CatrgotyResolver은 Restaurant.resolver.ts에 넣어서 만들도록한다.
그렇게 길지가 않아서..
그리고 slug로 category를 찾고 찾아진 categogy의 식당을 볼 수 있다.

1. all-category.dto.ts

import { Field, ObjectType } from '@nestjs/graphql';
import { MutationOutput } from 'src/common/dtos/output.dto';
import { Category } from '../entities/category.entity';

@ObjectType()
export class AllCategoriesOutput extends MutationOutput {
  @Field(() => [Category], { nullable: true })
  categories?: Category[];
}
///입력하는것 없이 Query로 바로 모든 카테고리 및 카테고리에 딸린, 식당을 볼 수 있음.

2. restaurant.resolver.ts

restaurant.resolver.ts안에 Category resolver를 같이 만든다.
따로 파일을 만들어도 상관은 없지만, category resolver 내용이
그렇게 많지 않아서 restaurant resolver안에 같이 만듬.

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

  @ResolveField(() => Int)
  restaurantCount(@Parent() category: Category): Promise<number> {
    return this.restaurantService.countRestaurants(category);
  }
  ///ResolverField는 apollo의 computed Field처럼 DB에는
  ///찍히지 않지만, DB들을 카운트, 라이크등등 처럼
  ///DB를 다룰 수 있음, restaurantCount는 카테고리에 따른
  ///식당 수를 카운팅 하는 API
  ///@Parent는 카티고리 DB를 받아옴.
  ///console.log(category)하면 알 수 있음.

  @Query(() => AllCategoriesOutput)
  allCategories(): Promise<AllCategoriesOutput> {
    return this.restaurantService.allCategories();
  }
///모든 카테고리를 받아 볼 수 있음.

3.restaurant.service.ts

  async allCategories(): Promise<AllCategoriesOutput> {
    try {
      const categories = await this.categories.find();
      return {
        ok: true,
        categories,
      };
    } catch {
      return {
        ok: false,
        error: 'Could not load categories',
      };
    }
  }
  ///모든 Category를 찾아서 return 해줌.

  countRestaurants(category: Category) {
    return this.restaurants.count({ category });
  }
  ///resolver의 restaurantCount Query의 service.
  ///category를 담아주면, category에 따른 restaurnat 카운트해줌.

1, Computed Field(restaurantCount)와
그것을 실행하기 위한, @Parent 부분을 한번더 복습한다,
2. Computed Field는 어디서든 자유롭게 사용 가능

4. common/dots/paginations.dto.ts

  import { Field, InputType, Int, ObjectType } from '@nestjs/graphql';
import { Restaurant } from 'src/restaurant/entities/restaurant.entity';
import { MutationOutput } from './output.dto';

@InputType()
export class PaginationInput {
  @Field(() => Int, { defaultValue: 1 })
  page: number;
}
///pagination을 받는 resolver에서는 공통적으로
///extends PaginationInput해 준다.
///page를 input으로 받기 위해서

@ObjectType()
export class PaginationOutPut extends MutationOutput {
  @Field(() => [Restaurant], { nullable: true })
  restaurants?: Restaurant[];

  @Field(() => Int, { nullable: true })
  totalPages?: number;

  @Field(() => Int, { nullable: true })
  totalResults?: number;
}
///pagination을 output받는 부분에 있어서는
///restaurants, totalPages, totalResults를
///받게 해 놓는다.

5. category.dto.ts


 import { Field, InputType, ObjectType } from '@nestjs/graphql';
import {
  PaginationInput,
  PaginationOutPut,
} from 'src/common/dtos/pagination.dto';
import { Category } from '../entities/category.entity';

@InputType()
export class CategoryInput extends PaginationInput {
  @Field(() => String)
  slug: string;
}
///category의 slug를 입력 받아서, slug에 따른 
///extends PaginationsInput을 확인한다.

@ObjectType()
export class CategoryOutput extends PaginationOutPut {
  @Field(() => Category, { nullable: true })
  category?: Category;
}
///extends PaginationOutput을 확인한다.

6. restaurant.resolver.ts

 @Query(() => CategoryOutput)
  category(
    @Args('input') categoryInput: CategoryInput,
  ): Promise<CategoryOutput> {
    return this.restaurantService.findCategoryBySlug(categoryInput);
  }

7. restaurant.service.ts

  async findCategoryBySlug({
    slug,
    page,
  }: CategoryInput): Promise<CategoryOutput> {
    try {
      const category = await this.categories.findOne(
        { slug },
        { relations: ['restaurants'] },
      );
      ///입력받은 slug로 category를 찾음.
      ///relations는 각 category에 연결된, restaurants를
      ///같이 불러주라는 뜻, 
      ///typeOrm이 3.**버젼이 되면서, 바뀌었는데, 확인해 볼 것!
      
      console.log(category);
      if (!category) {
        return {
          ok: false,
          error: 'Caterogy not found',
        };
      }
      ///category가 없으면, error 리턴
      
      const restaurants = await this.restaurants.find({
        where: { category },
        take: 25,
        skip: (page - 1) * 25,
      });
      ///slug에서 찾은 category로 식당을 load하는데,
      ///take:25, 한번에 25개를 불러오고,
      ///입력된 page에 따라, 각각의 page에 따라 식당을
      ///25개씩 load한다는 뜻.

      const totalResults = await this.countRestaurants(category);
      ///totalResults는 찾은 category리로 관련된 restaurants를
      ///countRestaurants computedField로 카운팅해서
      ///식당 수를 return해줌.
      
      return {
        ok: true,
        restaurants,
        category,
        totalPages: Math.ceil(totalResults / 25),
      };
      ///위에서 찾은, restauratns, category, totalPages등을
      ///return 해줌.
      
    } catch {
      return {
        ok: false,
        error: 'Could not load category',
      };
    }
  }
  1. computed Field를 확인.
  2. pagination을 구현하는 방법.
  3. page를 구현하는 방법등을확인한다.
profile
코딩하는초딩쌤

0개의 댓글