Tooling
Tooling
GraphQL ์ธ๊ณ์์ ๋ง์ ๊ธฐ์ฌ๋ ์ธ์ฆ(authentication) ๋๋ ๋ถ์์ฉ(side-effects)๊ณผ ๊ฐ์ ํญ๋ชฉ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ํด ๋ถํํฉ๋๋ค. ๋น์ฆ๋์ค ๋ก์ง์ ๋ฃ์ด์ผ ํฉ๋๊น? ์๋ฅผ ๋ค์ด ๊ถํ ๋ถ์ฌ ๋ ผ๋ฆฌ์ ๊ฐ์ด ์ฟผ๋ฆฌ์ ๋ฎคํ ์ด์ ์ ํฅ์์ํค๊ธฐ ์ํด ๊ณ ์ฐจ ํจ์๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๊น? ๋๋ ์คํค๋ง ์ง์์ด๋ฅผ ์ฌ์ฉํ์ญ์์ค. ์ด์จ๋ ํ๊ฐ์ง ๋ต์ ์์ต๋๋ค.
Nest ์ํ๊ณ๋ guards ๋ฐ interceptors์ ๊ฐ์ ๊ธฐ์กด ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๊ณ ํฉ๋๋ค. ๊ทธ ๋ฐฐํ์ ์์ด๋์ด๋ ์ค๋ณต์ฑ์ ์ค์ด๊ณ ๋ํ ์ฒด๊ณ์ ์ด๊ณ ์ฝ๊ธฐ ์ฝ๊ณ ์ผ๊ด์ฑ ์๋ ์์ฉ ํ๋ก๊ทธ๋จ์ ๋ง๋๋ ๋ฐ ๋์์ด ๋๋ ๋๊ตฌ๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ ๋๋ค.
Overview
๊ฐ๋จํ REST ์ ํ๋ฆฌ์ผ์ด์ ์์์ ๋์ผํ ๋ฐฉ์์ผ๋ก guards, interceptors, filters ๋๋ pipes๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ํ custom decorators ๊ธฐ๋ฅ์ ํ์ฉํ์ฌ ์์ ๋ง์ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฝ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค. ๊ทธ๋ค์ ๋ชจ๋ ๋๋ฑํ๊ฒ ํ๋ํฉ๋๋ค. ๋ค์ ์ฝ๋๋ฅผ ๋ณด์.
@Query('author')
@UseGuards(AuthGuard)
async getAuthor(@Args('id', ParseIntPipe) id: number) {
return await this.authorsService.findOneById(id);
}
๋ณด์๋ค์ํผ GraphQL์ ๊ฐ๋์ ํ์ดํ ๋ชจ๋์์ ์ ์๋ํฉ๋๋ค. ์๋ฅผ ๋ค์ด ์ธ์ฆ ๋ก์ง์ ๊ฐ๋๋ก ์ด๋ํ๊ฑฐ๋ REST ์ ํ๋ฆฌ์ผ์ด์ ์์์ ๋์ผํ ๊ฐ๋ ํด๋์ค๋ฅผ ์ฌ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ธํฐ์ ํฐ๋ ๋๊ฐ์ ๋ฐฉ์์ผ๋ก ์๋ํฉ๋๋ค.
@Mutation()
@UseInterceptors(EventsInterceptor)
async upvotePost(@Args('postId') postId: number) {
return await this.postsService.upvoteById({ id: postId });
}
Execution context
๊ทธ๋ฌ๋ ๊ฐ๋์ ์ธํฐ์
ํฐ ๋ชจ๋์ ์ํด ์์ ๋๋ ExecutionContext
๋ ์ฝ๊ฐ ๋ค๋ฆ
๋๋ค. GraphQL ๋ฆฌ์กธ๋ฒ์๋ ๊ฐ๊ฐ root
, args
, context
๋ฐ info
์ ๊ฐ์ ๋ณ๋์ ์ธ์ ์ธํธ๊ฐ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ฃผ์ด์ง ExecutionContext
๋ฅผ GqlExecutionContext
๋ก ๋ณํํด์ผ ํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค.
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
const ctx = GqlExecutionContext.create(context);
return true;
}
}
GqlExecutionContext
๋ getArgs()
, getContext()
๋ฑ๊ณผ ๊ฐ์ ๊ฐ ์ธ์์ ํด๋นํ๋ ๋ฉ์๋๋ฅผ ๋
ธ์ถํฉ๋๋ค. ์ด์ ํ์ฌ ์ฒ๋ฆฌ๋ ์์ฒญ์ ํน์ ํ ๋ชจ๋ ์ธ์๋ฅผ ์์ฝ๊ฒ ์ ํํ ์ ์์ต๋๋ค.
Exception filters
์์ธ ํํฐ๋ GraphQL ์์ฉ ํ๋ก๊ทธ๋จ๊ณผ๋ ํธํ๋ฉ๋๋ค.
@Catch(HttpException)
export class HttpExceptionFilter implements GqlExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const gqlHost = GqlArgumentsHost.create(host);
return exception;
}
}
info ํํธ
GqlExceptionFilter
์GqlArgumentsHost
๋ ๋ชจ๋@nestjs/graphql
ํจํค์ง์์ ๊ฐ์ ธ์ต๋๋ค.
๊ทธ๋ฌ๋ ์ด ๊ฒฝ์ฐ HTTP ์ฑ์์์ ๊ฐ์ด ๊ธฐ๋ณธ response
๊ฐ์ฒด์ ์ก์ธ์ค ํ ์ ์์ต๋๋ค.
Custom decorators
์์์ ์ธ๊ธํ๋ฏ์ด custom decorators ๊ธฐ๋ฅ์ GraphQL ๋ฆฌ์กธ๋ฒ์ ๋งค๋ ฅ์ฒ๋ผ ์๋ํฉ๋๋ค. ํฉํ ๋ฆฌ ํจ์๋ response
๊ฐ์ฒด ๋์ ์ธ์ ๋ฐฐ์ด์ ์ฌ์ฉํฉ๋๋ค.
export const User = createParamDecorator(
(data, [root, args, ctx, info]) => ctx.user,
);
๊ทธ๋ฆฌ๊ณ :
@Mutation()
async upvotePost(
@User() user: UserEntity,
@Args('postId') postId: number,
) {}
info ํํธ ์์ ์์์,
user
๊ฐ์ฒด๊ฐ GraphQL ์ดํ๋ฆฌ์ผ์ด์ ์ ์ปจํ ์คํธ์ ํ ๋น๋์๋ค๊ณ ๊ฐ์ ํ์ต๋๋ค.
Last updated
Was this helpful?