GraphQL - Query(Arguments, Aliases, Variables, Fragments, Directives)
목차
Query
이전 게시글에서 만든 내용을 Query로 조회하려면 아래와 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
query {
publishers {
id
name
location
publishedYear
books {
id
title
author
publisherId
reviews {
id
content
rating
bookId
}
tags {
id
name
}
}
}
}
이 기본적인 쿼리에 선택 사항을 하나씩 추가해보도록 하겠습니다.
Arguments
Arguments를 추가하하여 Query를 수정하면 아래와 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
query {
publisher(name:"테스트1"){
id
name
location
publishedYear
books {
id
title
author
publisherId
reviews {
id
content
rating
bookId
}
tags {
id
name
}
}
}
}
위와 같이 수정을 하면 모든 publishers가 아닌 특정 publishers(name이 “테스트1”)만 호출하게 되어 데이터 필터링이 이루어집니다.
Arguments를 사용하면 필요한 데이터만 요청하므로 네트워크 트랙픽이 감소하고 서버의 부하도 줄일 수 있습니다.
또한 클라이언트도 불필요한 데이터를 처리할 필요가 없어서 클라이언트의 메모리 사용량이 감소하고 데이터 처리 시간도 단축될 수 있습니다.
Aliases
Aliases는 동일한 필드를 다른 인자로 여러번 쿼리할 떄 유용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
query {
test:publisher(name:"테스트1"){
id
name
location
city:location
publishedYear
books {
id
title
author
publisherId
reviews {
id
content
rating
bookId
}
tags {
id
name
}
}
}
}
Aliases를 사용하면 서버의 필드 이름과 상관없이 클라이언트가 원하는 이름으로 데이터를 받을 수 있어 응답 데이터 구조를 커스터마이징이 가능합니다.
그렇기에 프론트엔드 코드의 구조를 조금 더 유연하게 설계할 수 있습니다.
또한 동일한 타입의 여러 객체를 한번의 쿼리로 가져올 수 있어 다중 쿼리 실행이 용이해집니다.
1
2
3
4
{
test_1:publisher(name: "테스트1") { ... }
test_2:publisher(name: "테스트2") { ... }
}
Variables
Variables가 전달되지 않았을 때 기본값으로 “테스트999”를 사용할 수 있게 설정합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
query GetPublisher($publisher_name: String = "테스트999") {
publisher(name: $publisher_name) {
id
name
location
city: location
publishedYear
books {
id
title
author
publisherId
reviews {
id
content
rating
bookId
}
tags {
id
name
}
}
}
}
Variables는 따로 설정을 아래와 같이 합니다.
1
2
3
{
"publisher_name": "테스트1"
}
Variables를 사용하면 변수의 타입을 명시적으로 선언할 수 있습니다.
잘못된 타입의 데이터가 전달되면 즉시 에러를 발생시켜 런타임 에러를 사전에 방지할 수 있습니다.
클라이언트에서 변수만 바꿔서 다양한 데이터를 요청할 수 있어 동적 쿼리 작성이 용이합니다.
또한 SQL 인젝션과 같은 보안 취약점을 방지할 수 있습니다.
Fragments
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
fragment PublisherDetails on Publisher {
id
name
location
city: location
publishedYear
}
query GetPublisher($publisher_name: String = "테스트999",
$publisher_name2: String = "테스트998") {
test1:publisher(name: $publisher_name) {
...PublisherDetails
}
test2:publisher(name: $publisher_name2) {
...PublisherDetails
}
}
1
2
3
4
{
"publisher_name": "테스트1",
"publisher_name2": "테스트2"
}
Fragment를 사용하면 코드 재사용성이 높아지고, 필드 구조가 변경될 때 Fragment만 수정하면 됩니다.
Directives
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
fragment PublisherDetails on Publisher {
id
name
location
city: location
publishedYear
}
query GetPublisher(
$publisher_name: String = "테스트999",
$publisher_name2: String = "테스트998",
$is_include: Boolean = true,
$is_skip: Boolean = false
) {
test1: publisher(name: $publisher_name) @include(if: $is_include) {
...PublisherDetails
}
test2: publisher(name: $publisher_name2) @skip(if: $is_skip) {
...PublisherDetails
}
}
1
2
3
4
5
6
{
"publisher_name": "테스트1",
"publisher_name2": "테스트2",
"is_include": true,
"is_skip": false
}
is_include
와 is_skip
을 true, false로 변경하면서 실행 결과를 확인해보는게 좋습니다.
1) @include 지시어
if 조건이 true일 때만 필드를 포함합니다
includeFirst: true → test1 데이터 포함
includeFirst: false → test1 데이터 제외
2) @skip 지시어
if 조건이 true일 때 필드를 제외합니다
skipSecond: true → test2 데이터 제외
skipSecond: false → test2 데이터 포함
이러한 지시어를 사용하면 클라이언트에서 필요한 데이터만 선택적으로 가져올 수 있어 효율적인 데이터 요청이 가능합니다.