들어가기
모든 카테고리(한식, 일식등등)를 보고,
카테고리에 딸린 식당 및, 식당 갯수등을
보는 API
CatrgotyResolver은 Restaurant.resolver.ts에 넣어서 만들도록한다.
그렇게 길지가 않아서..
그리고 slug로 category를 찾고 찾아진 categogy의 식당을 볼 수 있다.
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로 바로 모든 카테고리 및 카테고리에 딸린, 식당을 볼 수 있음.
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();
}
///모든 카테고리를 받아 볼 수 있음.
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는 어디서든 자유롭게 사용 가능
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를
///받게 해 놓는다.
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을 확인한다.
@Query(() => CategoryOutput)
category(
@Args('input') categoryInput: CategoryInput,
): Promise<CategoryOutput> {
return this.restaurantService.findCategoryBySlug(categoryInput);
}
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',
};
}
}