[GraphQL] Schema Based Validation

본 포스트는 공식 레퍼런스를 참고해 GraphQL을 공부하며 직접 작성한 가이드 입니다.
본 포스트는 2021년 7월 최신 버전인 v16.2를 기준으로 작성되어 있습니다.

Schema Validation

기존에 hibernate validation 방식은 검증할 인스턴스 변수에 @NotBalnk와 같은 어노테이션을 달아서 처리했다. 아직 버그가 존재하는 라이브러리이지만 스키마 기반으로 검증을 할 수 있는 라이브러리를 소개한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-extended-validation</artifactId>
<version>${graphql-schema-validation-verison}</version>
<exclusions>
<exclusion>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java</artifactId>
</exclusion>
<exclusion>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-extended-scalars</artifactId>
</exclusion>
</exclusions>
</dependency>

스키마 기반 검증이라 검증을 하고 싶은 스키마 필드에 어노테이션을 선언해주면 된다. 이를 확인하기 위해 간단한 뮤테이션을 선언하고 검증을 해보자.

1
2
3
4
5
6
7
type Mutation {
#웹툰 등록
createWebToon(input: WebToonInput!): WebToon!
updateWebtoon(id: ID!, title: String! @NotBlank): WebToon!
#파일 업로드
uploadFile: ID!
}

updateWebtoon이라는 뮤테이션에 title@NotBlank로 검증하도록 만들었다. 그리고 요청을 보내보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
# 웹툰 업데이트
mutation UPDATE_WEBTOON($id: ID!, $title: String!) {
updateWebtoon(id: $id, title: $title) {
id
title
webToonType
}
}

{
"id": "3568e088-ec83-11eb-9a03-0242ac130003",
"title": ""
}

로그를 확인하면 DataFectching 중에 검증을 하고 예외를 던진다. 그리고 응답으로 검증에 실패한 이유가 내려온다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"errors": [
{
"message": "Exception while fetching data (/updateWebtoon) : null",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"updateWebtoon"
],
"extensions": {
"classification": "DataFetchingException"
}
}
],
"extensions": {},
"data": null
}

물론 커스텀 메세지도 만들 수 있다. classPath 밑에 ValidationMessages.properties 안에 실패시 메세지를 선언하고 @NotBlank(message: "updateWebtoon.title")과 같이 선언하면 된다. 다만 베타 버전인지라 hibernate 디펜던시와 java-grpahql 디펜던시가 꼬여서 메세지가 내려오지 않았다.. 원인 찾느라 2시간 걸렸는데.. 나중에 시간나면 수정한 다음에 컨트리뷰션해야겠다.. 여하튼 커스텀 메세지와 i18n 관련은 ResourceBundleMessageInterpolator.class 구현을 보면 된다.

1
2
3
4
5
6
7
public class ResourceBundleMessageInterpolator implements MessageInterpolator {
private ResourceBundleLocator userResourceBundleLocator = new PlatformResourceBundleLocator("ValidationMessages");
private ResourceBundleLocator systemResourceBundleLocator = new PlatformResourceBundleLocator("graphql.validation.ValidationMessages");
private Locale defaultLocale = Locale.getDefault();

...
}

Repository

모든 가이드의 예제 코드는 SongHayoung/springboot-graphql-tutorial에서 확인할 수 있습니다.

Author: Song Hayoung
Link: https://songhayoung.github.io/2021/07/31/GraphQL/graphql-14/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.