Graphql Directive

오형근·2022년 4월 19일
0

Serverless

목록 보기
3/3

"fullstack Serverless" 책도 거의 반절이 넘는 챕터를 읽고 공부하였다.

전반적으로 AWS 기능을 사용하는 방법에 대해 매일 이해를 더하는 도중,
GQL의 스키마에 대한 정확한 이해가 아직 매우 부족하다는 것을 느꼈다.

그래서 책 내 Chapter8에 소개되어있는 GQL 스키마에 대한 짧은 리뷰를 해보려고 한다.

기본적인 GQL의 작동 알고리즘은 알고 있지만, 이번 글에서는 아직 지식이 미흡한 디렉티브에 대한 내용을 다뤄보려고 한다. Apollo Docs에 있는 문서와 Amplify Docs에 있는 내용을 내 입맛대로 정리한 것이기 때문에 혹시 수정할 내용이 있다면 언제든 피드백 부탁드립니다!

출처: Directives

Graphql 디렉티브?


Graphql 타입, 필드, 입력 값에 대한 도구

디렉티브는 Graphql 스키마를 작성하고 리졸버로 호출하는 과정에서 특정 작업을 수행할 수 있도록 해주는 추가적인 도구이다. 디렉티브는 @ 문구를 통해 선언할 수 있다.

schema.graphql

type ExampleType {
  oldField: String @deprecated(reason: "Use `newField`.")
  newField: String
}

위의 예시에서는 @deprecated 디렉티브가 사용되었는데, 같이 전달되는 reasontrue인 경우 해당 스키마를 제외한다는 의미를 가진다. 이 디렉티브는 기본적으로 graphql에서 제공되는 디렉티브인데, 이 외에도

@skip(if: Boolean!) : if 값이 true를 반환하면 해당 스키마는 읽히지 않는다.
@include(if: Boolean!) : if 값이 false를 반환하면 해당 스키마는 읽히지 않는다(@skip과 반대).

이렇게 세 가지 기본 디렉티브를 제공한다.

사용 가능한 위치

디렉티브는 아무 곳에서나 사용 가능한 도구가 아니다. 각 디렉티브의 정의를 살펴보면 사용할 수 있는 위치가 정해져있는데, 그 예시는 다음과 같다.

schema.graphql

directive @deprecated(
  reason: String = "No longer supported"
) on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | ENUM_VALUE

위의 예시에서 볼 수 있듯이 @deprecated 디렉티브는 네 곳의 필드에서만 적용이 가능하다. 또한 위의 reason argument는 선택값이며 "No longer supported"가 기본으로 들어가 있음을 알 수 있다.

다음 예시를 살펴보자.

schema.graphql

# ARGUMENT_DEFINITION
# Note: @deprecated arguments _must_ be optional.
directive @withDeprecatedArgs(
  deprecatedArg: String @deprecated(reason: "Use `newArg`"),
  newArg: String
) on FIELD

type MyType {
  # ARGUMENT_DEFINITION (alternate example on a field's args)
  fieldWithDeprecatedArgs(name: String! @deprecated): String
  # FIELD_DEFINITION
  deprecatedField: String @deprecated
}

enum MyEnum {
  # ENUM_VALUE
  OLD_VALUE @deprecated(reason: "Use `NEW_VALUE`.")
  NEW_VALUE
}

input SomeInputType {
  nonDeprecated: String
  # INPUT_FIELD_DEFINITION
  deprecated: String @deprecated
}

많이 쓰이는 디렉티브

위에서 설명한 default directive 외에도 다양하게 쓰이는 디렉티브가 많다.

특히, 내가 공부 중인 AWS-Amplify에서 유용한 디렉티브를 여럿 제공한다.

내가 자주 사용하고 있는 디렉티브는 다음과 같다.

@model

@model 디렉티브는 우리가 특정 타입을 정의하였을 때, 이 타입에 대한 CRUD 모델을 자동적으로 생성해주는 디렉티브이다.

schema.graphql

type Poem @model {
	id: ID!
    title: String!
    author: String!
    detail: String!
}

위의 코드와 같이 @model 디렉티브를 추가하면 Poem에 대한 CRUD 기능이 자동적으로 생성되고, 자동으로 Amplify S3를 이용한 DynamoDB와의 연결이 진행된다.

즉, CRUD 생성 및 DB 연동을 자동적으로 진행한다는 이야기이다..!

AWS에 명시되어있는 @model 디렉티브의 기능은 다음과 같다.

  • 쿼리와 뮤테이션에 대한 추가적인 스키마 정의(Create, Read, Update, Delete, List 작업)
  • GQL subscription에 대한 추가적인 스키마 정의
  • DynamoDB
  • DynamoDB 에 매핑된 모든 GQL 작업에 대한 리졸버 코드

@auth

Auth@model만큼이나 자주 사용되는 기능으로, 우리가 특정 쿼리에 접근할 때 해당 쿼리가 가능한 이를 구분하고 검증하는 기능을 담고 있다.

auth 디렉티브를 사용하면 권한 규칙을 설정할 수 있다. 각 규칙에는 필수적으로 allow 필드가 존재한다. 이 외에도 인증 방법을 지정하는 provider 같은 다양한 메타데이터도 선택적으로 작성할 수 있다.

이에 대한 예시를 살펴보자.

schema.graphql

type Stage @model {
	@auth(rules: [
    { allow: public, oprations: [read],
    { allow: groups, groups: ["Admin"] }
    )}

예제에서는 public 접근과 groups 접근 두 권한 타입을 사용하였고, public 접근에 대해서는 활성화할 작업 목록을 설정하는 operations도 사용하였다. operations가 설정되지 않으면 모든 작업이 활성화된다.

@key

@key 디렉티브는 AWS DynamoDB 테이블 상에서 값 조회를 위한 추가적인 GSI 및 정렬 키를 추가할 수 있도록 한다. 해당 디렉티브를 사용해서 원하는 키값으로 정렬을 할 수도 있고, 쿼리를 통해 조회할 수도 있다.

schema.graphql

type Performance @model {
	@index(name: "byStageId", sortKeyFields: ["stageId"], queryField: ["performanceStageId"]
    @auth(ruls: [
    { allow: public, operations: [read] },
    { allow: groups, groups: ["Admin"] }
)}

위의 예시처럼 사용하면 performanceStageId 필드에서 stageId 키를 생성했다. 이를 통해 키에 해당하는 테이블값을 조회할 수 있다.

다만 내가 사용하는 과정에서 @key 대신 @index를 사용하였는데, 업데이트된 버전에서는 @key 사용보다 세분화된 새로운 디렉티브를 사용하기를 권장하는 듯 했다. 정확한 문서가 없어 같은 역할을 하는 디렉티브라고 생각하면 좋을 것 같다. 에러 메세지와 함께 나오는 링크에 자세한 설명이 있으니 참고하자.

@connection

이 또한 새로운 디렉티브로 세분화되었다. 본래 타입 간 관계를 모델링하는 데 사용하는데, 일대다 / 다대일 / 다대다 의 관계를 정의한다. 이제는 각각 @hasOne, @hasMany, @belongsTo, @manyToMany로 정의된다.

schema.graphql

type Stage @model {
	id: ID!
    name: String!
    performances: [Performance] @hasMany 
}
    
type Performance @model {
	id: ID!
    performanceStageId: ID!
    productId: ID
    performer: String!
    imageUrl: String
    description: String!
    time: String
    stage: Stage @hasOne

위의 예시처럼 타입에 대한 관계를 설정할 수 있다!


지금까지 GQL에서 제공하는 디렉티브의 기본적인 내용을 살펴보았다.

다음에는 현재 AWS Amplify 연습을 위해 간단하게 제작하고 있는 POEM IT 사이트에 대한 내용을 마저 작성할 예정이다.

profile
https://nohv.site

0개의 댓글