티스토리 뷰

GraphQL(GraphQueryLanguage) 란?

위 글에서 GraphQL에 대해 소개하는 시간을 가졌다. GraphQL을 이용한 API를 구현하기 위해서는 스키마(Schema)를 작성할 수 있어야한다.

스키마는 데이터 타입의 집합으로 API 문서 역할을 한다. GraphQL API를 설계할 때엔 스키마를 먼저 정의하게 되며 이 스키마에는 어떤 종류의 객체를 반환할 지 내가 받을 수 있는 자원은 어떤 종류인지 어떠한 자원을 인자로 받는지가 정의되어있다.

 

# 스칼라 (Scalar)

스칼라 타입은 gql schema에서 쪼개질 수 없는 가장 작은 단위이며 5가지 기본 타입이 존재한다.

  1. Int : 부호가 있는 32비트 정수
  2. Float : 부호가 있는 부동소수점 값
  3. String : UTF-8 문자열
  4. Boolean : true/false
  5. ID : 고유 식별자 값으로 String과 같은 방법으로 직렬화 되지만 ID로 정의 한다는 의미는 사람이 읽으라고 만든 의도가 아님을 의미함

또한 GraphQL에서는 커스텀 스칼라 타입을 지정하는 것도 가능하다

scalar {DataType}

# Type

GraphQL 스키마의 핵심 단위이며 C나 JAVA에 익숙한 사람들은 객체라고 생각하면 편할 것이다                                  

type Car{
    ModelName: String!
    ModelCode: Int!
    MadeAt: Int
    Credit: [Name]!
}
  • Car는 GraphQL 객체 타입이다. 이는 필드가 있는 타입을 의미하며 스키마의 대부분의 타입은 객체 타입이다.
  • ModelName, ModelCode, MadeAt, Credit은 Car타입의 필드이다. 각각의 필드는 특정 종류(스키마에 정의 된 종류)의 데이터를 반환하며, 이 때 커스텀 객체 타입, 리스트, 스칼라 타입중 여러 형태의 데이터를 반환한다.
  • String! 나 Int!에 붙은 !는 해당 필드가 non-nullable임을 의미하는 것이다. 즉 이 필드를 쿼리할 때 GraphQL 서비스는 항상 값을 반환한다는 것을 의미한다. (null값을 허용하지 않는다를 의미 함)
  • [Name]!은 Name 객체의 배열(array)를 나타낸다. 또한 !으로 정의되어 있기 때문에 Credit 필드를 쿼리 할 때 항상 0개 이상의 Name을 아이템을 가진 배열을 기대할 수 있다. 

# Non-Null

Type에서 먼저 소개한 Non-Null 은 필드에 대한 인자(파라미터)를 정의할 때도 사용할 수 있다.

type Query{
    class(classNum: Int!) : Class
}
type Class{
    ClassNum: Int!
    students: [Student]
    teachers: [Teacher]
} 
..........

다음과 같이 인자[괄호'()'로 표시 됨]인 classNum의 Int 타입에 !를 추가하여 인자를 Non-Null로 만들었다. 

이렇게 설정했을 경우 인자인 classNum이 null값으로 전달된다면 유효성 검사 오류를 반환 할 것이다.

# 리스트

리스트도 Type에서 이미 언급하였지만 다시 설명하자면 스칼라 타입이나 커스텀 리스트 등 다양한 리스트 형태로 정의할 수 있다. 또한 !와 같이 쓸 경우 !의 위치에 따라서 의미가 달라진다.

  • [Type] - 리스트 안에 담긴 Type은 null 혹은 특정 값이 존재한다.
  • [Type!] - 리스트 안에 담긴 Type은 null이 될 수 없으며 반드시 특정 값이 존재한다.
  • [Type]! - 리스트 안에 담긴 Type은 null일 수 있으나, 리스트 자체는 null이 될 수 없다.
  • [Type!]! - 리스트 안에 담긴 Type도, 리스트 자체도 null이 될 수 없다.

# 열거형 타입

Enums이라고도 하는 열거형 타입은 특정 값들로 제한되는 특별한 종류의 스칼라이다.

열거형 타입으로 스칼라를 정의하면 해당 Enums을 타입으로 가지는 필드는 항상 열거형 집합 중 하나의 값을 가진다.

enum Grade{
    A+
    A0
    B+
    B0
    C+
    C0
    D+
    D0
    F
}

type Student{
    name: String
    id: ID
    age: Int
    grade: Grade
}

다음과 같이 스키마를 정의하면 Student 타입의 grade필드는 항상 A+,A0,B+,B0,C+,C0,D+,D0,F 값들 중 하나의 값을 가진다.

 

# 인자(Parameter)와 입력 타입(Input type)

아까 #Non-null에서 잠깐 언급하였듯 스키마를 작성할 때 인자(Parameter)를 정의해줄 수 있다.

type Query{
    Student(name: String):[Student]
}
type Student{
    name: String
    age: Int
}

위와 같이 Query안의 Student는 name이라는 인자를 가지고 있다. resolver에서 어떻게 정의해주느냐에 따라 다르겠지만 사용자는 query할 때 Student에 name란에 적절한 인수를 넣어주면 그에 따른 값을 반환 받을 수 있을 것이다.

 

그리고 이러한 인자는 스칼라 형태가 아니라 타입 형태로도 작성 가능하다.

입력 타입은 type대신 input으로 정의된다.

type Example{
    x:String
    y:String
}
input ExampleInput{
    x:String
    y:String
}
type Query{
    getOutput(example: Example): Example  //type형을 인자로 받지 않고 아래에 선언 된 걸 사용
    getOutput(example: ExampleInput): Example
}

다음과 같이 Query안의 두 필드 중 아래 필드 처럼 사용하게 된다.

type 대신 input 타입을 사용하는 이유는 여기에 자세히 나와으니 한번 쯤 읽어보면 좋을 듯하다.

 

'서버 관련 > Backend 지식' 카테고리의 다른 글

GraphQL 스키마 작성하기 (GraphQL Schema)  (0) 2020.04.18
GraphQL(Graph Query Language) 란?  (0) 2020.04.16
REST API 란?  (0) 2020.04.09
댓글
댓글쓰기 폼