Tooling

Tooling

GraphQL 세계에서 많은 기사는 인증(authentication) 또는 부작용(side-effects)과 같은 항목을 처리하는 방법에 대해 불평합니다. 비즈니스 로직에 넣어야 합니까? 예를 들어 권한 부여 논리와 같이 쿼리와 뮤테이션을 향상시키기 위해 고차 함수를 사용해야 합니까? 또는 스키마 지시어를 사용하십시오. 어쨌든 한가지 답은 없습니다.

Nest 생태계는 guardsinterceptors와 같은 기존 기능을 사용하여 이 문제를 해결하려고 합니다. 그 배후의 아이디어는 중복성을 줄이고 또한 체계적이고 읽기 쉽고 일관성 있는 응용 프로그램을 만드는 데 도움이 되는 도구를 제공하는 것입니다.

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, contextinfo와 같은 별도의 인수 세트가 있습니다. 따라서 주어진 ExecutionContextGqlExecutionContext로 변환해야 합니다. 기본적으로 매우 간단합니다.

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;
  }
}

GqlExecutionContextgetArgs(), getContext()등과 같은 각 인수에 해당하는 메소드를 노출합니다. 이제 현재 처리된 요청에 특정한 모든 인수를 손쉽게 선택할 수 있습니다.

Exception filters

예외 필터는 GraphQL 응용 프로그램과도 호환됩니다.

@Catch(HttpException)
export class HttpExceptionFilter implements GqlExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const gqlHost = GqlArgumentsHost.create(host);
    return exception;
  }
}

info 힌트 GqlExceptionFilterGqlArgumentsHost는 모두 @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