[GraphQL] GraphQL의 스키마 고급 - Input, Enum, Union, Interface
Input Type
Input Type은 여러 데이터 필드를 인수로 사용할 수 있게 해주는 특수한 Object Type이다.
Object Type을 정의할 때와 비슷하지만 키워드를 input으로 사용한다.
input PostContent {
title: String!
content: String!
}
선언 후 Query, Mutation Subsctiption 등 다양한 타입의 입력 인수로 사용할 수 있다.
Input Type 사용 예시
type Mutation {
createPost(postContent: PostContent!): Post
updatePost(id: ID!, postContent: PostContent!): Post
}
위와 같이 생성과 업데이트에 같은 Input Type을 사용하고 있지만, 각각의 요청이 다를 수 있으므로 재사용을 너무 많이 하지말라고 경고하고 있다.
마찬가지로 Query와 Mutation의 같은 Input Type은 특히 주의해라고 한다.
Enum Type
일반적으로 프로그래밍 언어에서 사용하는 Enum Type과 거의 유사한 타입이다.
enum Color {
RED
GREEN
BLUE
}
Enum Type은 클라이언트에서 규정된 목록에서 선택해야 하는 상황에서 유용하게 사용할 수 있다.
추가적으로, Enum Type은 Apollo Studio Explorer와 같은 도구에서 자동 완성이 된다.
Enum Type 사용 예시
type Query {
userColor: Color
setUserColor(userColor: Color): String
}
다른 Scalar Type들과 마찬가지로 반환값으로도 사용할 수 있고, 입력값으로도 사용할 수 있다.
query SetUserColor {
setUserColor(userColor: RED)
}
Query에 사용할 땐 위와 같이 사용할 수 있다.
Union Type
Union Type은 여러 종류의 Object Type 중 하나가 될 수 있는 타입을 정의하는데 사용한다.
Union Type을 반환 타입으로 지정하면 Union에 포함된 Object Type 중 하나가 반환될 수 있다.
union SearchResult = User | Post
이 정의는 SearchResult 라는 Union Type을 정의했고, User 또는 Post 중 하나를 가질 수 있다.
Union Type 사용 예시
type Query {
search: [SearchResult!]!
}
예시의 search 쿼리는 User 또는 Post 타입 중 하나를 반환하게 된다.
query SearchQuery {
search {
__typename
... on User {
id
name
email
}
... on Post {
id
title
content
}
}
}
Query에 사용할 땐 위와 같이 사용할 수 있다.
각각의 타입에 대해 받을 필드를 지정을 한다.
그리고 클라이언트에서는 어떤 타입을 받았는지에 대한 구분을 위해 __typename 필드를 사용해서 결과가 User타입인지 Post타입인지 구분하여 해당 타입에 맞게 사용할 수 있다.
Interface Type
Interface Type은 여러 Object Type간에 공통 필드를 정의하고, 여러 타입들이 공통 필드를 구현하도록 강제하는 역할을 한다.
interface Post {
title: String!
}
이 정의는 Post 라는 interface type을 정의했고, 필수의 String title 필드를 가지고있다.
Interface Type 사용 예시
type ImagePost implements Post {
title: String! # 필수 구현
imageUrl: String!
}
type ContentPost implements Post {
title: String! # 필수 구현
content: String!
}
예시의 ImagePost와 ContentPost는 Post Interface를 구현하고있다.
각 타입은 Post Interface에서 정의한 title 필드를 포함하고 있어야하고, 추가로 자신의 고유한 필드를 가질 수 있다.
query SearchPost {
post {
__typename
... on ContentPost {
title
content
}
... on ImagePost {
title
imageUrl
}
}
}
Union Type과 마찬가지로 각각의 타입에 맞는 필드들을 불러올 수 있고, 클라이언트에서는 구분하기 위해 __typename 필드를 사용할 수 있다.