| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 | 27 | 28 | 29 | 30 |
- proxy
- CS
- 스프링 시큐리티
- 스프링
- 운영체제
- 리플렉션
- 객체지향
- spring security
- 백준
- 알고리즘
- 약수
- MST
- 모던자바
- 자바
- test
- Python
- Reflection
- Deadlock
- 모던 자바 인 액션
- 다이나믹 프록시
- Spring
- 최소 신장 트리
- redis
- 파이썬
- java
- BOJ
- Junit5
- OS
- 프록시
- 문자열
- Today
- Total
Dev 달팽이 @_''
[GraphQL] 공식문서 - Schemas and Types 본문
Schemas and Types
Object types and fields
- GraphQL의 가장 기본 컴포넌트는 object type
- Object type은 서비스에서 fetch할 수 있는 객체와 어떤 필드가 있는지로 구성
- 예 :
type Character {
name: String!
appearsIn: [Episode!]!
}
- Character는 GraphQL Object Type
- name과 appearsIn은 Character type의 필드
- String은 scalar 타입으로 query에서 하위 선택을 가질 수 없음
- String! 은 해당 필드가 null이 될 수 없음을 뜻
- [Episode!]! 는 Episode 객체의 배열을 표현, Episode! 이므로 항상 0개 또는 하나 이상의 배열이 리턴
Arguments
- GraphQL에 모든 필드는 0개 또는 여러 개의 arguments를 가질 수 있음
- 모든 Arguments는 이름을 가지고 있음
The Query and Mutation types
- Schema에는 보통 일반 object type
- 그러나 2개의 특별한 타입이 존재
schema {
query: Query
mutation: Mutation
}
- 모든 GraphQL 서비스는 query type과 mutation type(선택)을 가지고 있음
- 두 타입은 일반적인 object type과 같음
- 그러나 모든 GraphQL query의 entry point(첫 부분)에서 정의된다는 점이 특별
- 예 :
Request
query {
hero {
name
}
droid(id: "2000") {
name
}
}
Response
{
"data": {
"hero": {
"name": "R2-D2"
},
"droid": {
"name": "C-3PO"
}
}
}
type Query {
hero(episode: Episode): Character
droid(id: ID!): Droid
}
- 위의 GraphQL service의 의미는 Query type에 있어야하고 hero와 droid 필드가 포함되어 있다는 의미
- Mutation도 비슷한 방법으로 동작
- Muation type과 포함되는 필드를 정의하고 query에서 호출하여 사용
Scalar types
- GraphQL object type은 이과 필드를 가지고 있음
- 그러나 이 필드들 역시 어느 시점에서는 구체적인 데이터를 다뤄야 함
- 이 때, scalar 타입이 쓰일 수 있고 이들은 query의 leaves라고 함
- GraphQL의 기본 Defualt Scalar
- Int : A signed 32-bit integerd
- Float : A signed double-precision floating-point valuee
- String : A UTF-8 character sequence
- Boolean : true or false
- ID : unique identifier, 종종 object나 cache key를 refetch할 때 사용
- 대부분은 custom scalar types를 정의해서 사용
- 예 :
scalar Date
- 어떻게 타입이 serialized/deserialized/validated 되어야 하는지를 정의하는 것은 구현에 달려있음
Enumeration types
- Enums이라 불리는 enumeration types은 특별한 종류의 scalar가 존재
- enum의 효과
- 이 타입의 모든 arguments가 허용된 값 중 하낭인지 유효성 검사
- 어떠한 필드가 항상 유한한 값들의 집합 중 하나가 될 것이라는 것을 타입 시스템을 통해 전달
- 예 :
enum Episode {
NEWHOPE
EMPIRE
JEDI
}
- 위의 의미는 schema에서 Episode type을 사용하며, NEWHOPE, EMPIRE, JEDI 중 하나의 값
Lists and Non-Null
- Object types, scalars, enums은 GraphQL에서 정의할 수 있는 유일한 타입
- schema의 다른 파트에서 타입을 쓸 때나, query variable 선언에서 해당 값들의 유효성에 영향을 주는 추가적인 타입 modifier들을 적용 가능
- 예 :
type Character {
name: String!
appearsIn: [Episode]!
}
- 위의 예에서 String 뒤에 !를 추가함으로써 Non-Null 값을 명시
- Non-Null modifier는 필드에 argument를 정의할 때에도 사용 가능
- 예 :
Request
query DroidById($id: ID!) {
droid(id: $id) {
name
}
}
// Variables
{
"id": null
}
Response
{
"errors": [
{
"message": "Variable \"$id\" of non-null type \"ID!\" must not be null.",
"locations": [
{
"line": 1,
"column": 17
}
]
}
]
}
- List도 비슷한 방식으로 동작
Interfaces
- GraphQL도 interface를 지원
- Interface는 abstract type이며 반드시 포함해야 하는 특정 필드 집합을 정의
- 예 :
interface Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
}
- 위의 예에서 Character를 구현하는 어떤 타입이건 이 필드들 그리고 arguments와 리턴 타입을 똑같이 가지고 있어야 함을 의미
type Human implements Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
starships: [Starship]
totalCredits: Int
}
type Droid implements Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
primaryFunction: String
}
- 위에 예에서 둘 다 Character의 필드들을 모두 가지고 있으며 각각 추가적인 필드가 존재
- Interface는 다른 타입이지만 객체나 객체의 셋을 리턴하고자 할 때 유용
- 예 :
Request
query HeroForEpisode($ep: Episode!) {
hero(episode: $ep) {
name
primaryFunction
}
}
// Variables
{
"ep": "JEDI"
}
Response
{
"errors": [
{
"message": "Cannot query field \"primaryFunction\" on type \"Character\". Did you mean to use an inline fragment on \"Droid\"?",
"locations": [
{
"line": 4,
"column": 5
}
]
}
]
}
- 위에 예에서 error를 리턴(hero 필드는 Character 타입을 반환, episode에 따라 Human이 되거나 Droid가 될 수 있음)
- Character interface에만 존재하는 피드만 요청 가능ㅇ
- 특정 객체 타입에만 있는 필드를 요청하기 위해서는 inline fragment를 사용
- 예 :
Request
query HeroForEpisode($ep: Episode!) {
hero(episode: $ep) {
name
... on Droid {
primaryFunction
}
}
}
// Variables
{
"ep": "JEDI"
}
Response
{
"data": {
"hero": {
"name": "R2-D2",
"primaryFunction": "Astromech"
}
}
}
Union types
- Union type은 interface와 비슷하나 타입 간 공통 필드를 명시하지 않음
- 예 :
union SearchResult = Human | Droid | Starship
- Schema에서 SearchResult 타입을 리턴할 때마다 Human, Droid 또는 StarShip을 얻을 수 있음
- union type의 구성 요소들은 반드시 구체적인 객체 타입이어야 함
- interface 혹은 다른 union 타입 불가
- 이 경우, union type의 SearchResult를 리턴하는 필드에 쿼리를 넣는다면, 필드에 쿼리를 하기 위해서 반드시 조건부 fragment를 사용 해야함
- 예 :
Request
{
search(text: "an") {
__typename
... on Human {
name
height
}
... on Droid {
name
primaryFunction
}
... on Starship {
name
length
}
}
}
Response
{
"data": {
"search": [
{
"__typename": "Human",
"name": "Han Solo",
"height": 1.8
},
{
"__typename": "Human",
"name": "Leia Organa",
"height": 1.5
},
{
"__typename": "Starship",
"name": "TIE Advanced x1",
"length": 9.2
}
]
}
}
- __typename 필드는 클라이언트에서 서로 다른 데이터 유형을 구별할 수 있는 문자열
- 위의 예에서 Human과 Droid는 공통 interface(Character)를 공유하므로 여러 유형에서 동일한 필드는 한 곳에서 쿼리 가능
- 예 :
Request
{
search(text: "an") {
__typename
... on Character {
name
}
... on Human {
#name
height
}
... on Droid {
#name
primaryFunction
}
... on Starship {
#name
length
}
}
}
Response
{
"data": {
"search": [
{
"__typename": "Human",
"name": "Han Solo",
"height": 1.8
},
{
"__typename": "Human",
"name": "Leia Organa",
"height": 1.5
},
{
"__typename": "Starship",
"length": 9.2
}
]
}
}
Input types
- Arguments로 복합 Object를 넘길 수 있음
- 특히 mutation에서 중요
- 키워드가 type이 아니라 input
- 예 :
input ReviewInput {
stars: Int!
commentary: String
}
Request
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}
// Variables
{
"ep": "JEDI",
"review": {
"stars": 5,
"commentary": "This is a great movie!"
}
}
Response
{
"data": {
"createReview": {
"stars": 5,
"commentary": "This is a great movie!"
}
}
}
- Input 객체 타입의 필드는 input 객체 타입을 참조할 수 있지만, Schema에 input과 output 타입을 섞을 순 없음
- Input 객체 타입은 필드에 argument를 가질 수 없음
'GraphQL' 카테고리의 다른 글
| [GraphQL] 공식문서 - Queries and Mutations (1) | 2022.10.05 |
|---|