본문 바로가기

GraphQL

[GraphQL] GraphQL의 스키마 기초 - Scalar, Object, Type, Query, Mutation, Subscripstion

[GraphQL] GraphQL이란, GraphQL vs REST API

GraphQL의 특징Facebook에서 개발한 데이터 쿼리 언어로, API 요쳥을 최적화하는 것을 목적으로 한다.GraphQL은 REST API의 대안으로 사용된다.클라이언트 주도 데이터 요청: 클라이언트는 필요한 데이터

kanoos-stu.tistory.com

 


 

SDL (Schema Definition Languege )

GraphQL의 스키마를 정의하는 언어
SDL을 사용해서 쿼리와 데이터 모델을 설명하고, 클라이언트 - 서버 간의 명세를 공유할 수 있다.
SDL의 구성 요소

  • Scalar Type
  • Object Type
  • Query Type
  • Mutation Type
  • Subscription Type
  • Input Type
  • Enum Type
  • Interface
  • Union Type

 


 

Scalar Type

Scalar Type은 일반적으로 프로그래밍 언어에서 사용하는 타입과 비슷하다.

  • Int: 32비트 정수
  • Float: 부동 소수
  • String: 문자열
  • Boolean: true 또는 false
  • ID: 고유 식별값, String으로 직렬화 된다.

대부분의 사용 사례에서는 해당 Scalar Type만 으로도 충분하다.
추가적으로 필요한 경우 각각의 서버 프로그래밍 언어를 통해 Custom Scalar Type을 만들 수 있다.
 


 

Object Type

GraphQL 스키마에서 정의되는 대부분의 유형은 Object Type이다.
Object Type은 여러 Scalar Type의 필드로 구성된다.

Object Type 예시

 

type User {
    id: ID!
    posts: [Post]
    age: Int!
    name: String!
    email: String
}

type Post {
    user: User!
    title: String!
    content: String!
    isLike: Boolean!
}
  • List Field
    • 특정 Object Type이나 Scalar Type의 List 형태를 반환한다.
    • 대괄호 []로 감싸서 표시한다.
    • 여기서는 [Post] 를 통해 Post Object Type을 반환하고 있다.
  • non-nullable
    • GraphQL에서 non-nullable을 지정하기 위해 ! 를 붙여준다.
    • 여기서는 ID!, Int!, String! 같은 타입들이 non-nullable에 해당한다.
    • 그 외에 String, Post 같은 타입은 nullable 이 된다.
  • List의 nullable, non-nullable
    • List에서는 ! 의 위치에 따라 여러가지 조합이 가능하다
    • [Post] - null, [null], [], [{user: User}]
    • [Post!] - null, [], [{user: User}] / [null] 반환은 불가능하다.
    • [Post]! - [null], [], [{user: User}] / null 반환은 불가능하다.
    • [Post!]! - [], [{user: User}] / null, [null] 반환은 불가능하다.
  • __typename
    • 모든 Object Type 은 정의하지 않아도 __typename 필드가 자동으로 생성된다.
    • __typename 필드는 Object Type의 이름을 반환한다. (예: Post)
    • 이 필드는 여러 유형을 반환할 수 있는 (이후에 알아볼 Union 또는 Interface) 필드의 유형을 판별하는 데 사용된다.

 

  1.  

 


 

Query Type

Query Type은 클라이언트가 서버에 요청하는 쿼리에 대한 모든 읽기 entry point를 정의하는 객체 유형이다.
Query Type에는 각각의 다른 entry point의 이름과 return type을 정의해야한다.

Query Type 예시

type Query{
    users: [User!]
    posts: [Post!]
}

해당 Query는 두 개의 필드가 정의 되어있고, 각각 User list와 Post list를 반환하도록 지정되었다.
 

Query 요청 예시

{
    users {
        name
        email
        posts {
            title
            content
        }
    }
}

클라이언트에서 해당 Query Type을 요청할 때 위와 같이 작성할 수 있다.
해당 요청은 모든 유저를 조회하고, 유저에는 각각 name, email, posts가 포함되어잇다.
posts는 post의 리스트이고 각각 title과 content가 포함되어있다.
 

반환값

{
    "data": {
        "users": [
            {
                "name": "User Name",
                "email": "user@example.com",
                "posts": [
                    {
                        "title": "Post Title",
                        "content": "Post content goes here"
                    },
                    ...
                ]
            },
            ...
        ]
    }
}

SDL에 정의한 필드가 요청 Query에 포함되지 않으면 해당 필드는 제외되어 값을 반환한다.
 


 

Mutation Type

Mutation은 Query와 구조가 거의 비슷하지만, 데이터를 변경하는 작업에 대한 entry point를 정의한다.
예를 들어, 사용자를 생성하거나 업데이트할 때 사용된다.
Mutation을 정의할 때도 마찬가지로 entry point의 각각 다른의 이름과, 반환값을 정의할 수 있다.

type Mutation {
  createUser(name: String!, email: String, age: Int!): User
}

 해당 Mutation은 이름과 나이를 필수로 받고 옵션으로 email을 받아 유저를 생성한다.
그리고 생성된 유저의 정보를 반환하고 있다.
 

Mutation 요청 예시

mutation CreateUser {
  createUser(name: "burger", email: "burger@kim.com", age: 30) {
    name
    email
    age
  }
}

클라이언트에서 해당 Mutation Type을 요청할 때 위와 같이 작성할 수 있다.
해당 요청은 이름 burger, email burger@kim.com 나이 30살의 유저를 생성하고, 생성된 유저의 name, email, age를 반환한다.
 

반환값

{
    "data": {
        "createUser": {
            "name": "burger",
            "email": "burger@kim.com",
            "age": 30
        }
    }
}

마찬가지로 SDL에 정의한 필드가 요청에 포함되지 않으면 해당 필드는 제외되어 값을 반환한다.


 

Subscription Type

Subscriptions는 서버에서 발생하는 이벤트를 실시간으로 클라이언트에게 전송한다.
주로 채팅 애플리케이션같은 WebSocket 프로토콜을 통해 실시간 업데이트를 받아야 할때 사용된다.
Subscription을 정의할 때도 마찬가지로 entry point의 각각 다른의 이름과, 반환값을 정의할 수 있다.

type Subscription {
    postCreated: Post
}

postCreated 필드는 서버에서 새 게시글이 작성될 때마다 값을 업데이트하여 해당 Subscription을 구독하는 클아이언트에게 게시물 데이터를 푸시한다.
 

Subscription 요청 예시

클라이언트는 다음과 같이 GraphQL 문자열을 사용해서 postCreted 필드를 구독할 수 있다.

subscription PostCreated {
  postCreated {
    title
    content
    user
  }
}

subscription 요청은 한번에 하나만 구독할 수 있다.