GraphQL의 Schema와 Scalar

eeensu·2023년 8월 8일
0

GraphQL

목록 보기
6/6
post-thumbnail

스키마 (Schema)

GraphQL 스키마는 GraphQL API의 타입들과 어떤 작업이 가능한지를 정의하는 중요한 구성 요소이다. 스키마는 서버와 클라이언트 간의 커뮤니케이션을 위해 사용되는 데이터 모델의 설계 도구이며 이는 데이터의 구조, 쿼리, 뮤테이션 등이 어떻게 정의되는지를 명시한다.


언어 정의

GraphQL 쿼리는 형태와 결과가 거의 일치하기 때문에 서버에 대해 모르는 상태에서 쿼리가 반환할 결과를 예측할 수 있다. 하지만 서버에 요청할 수 있는 데이터의 정확한 표현을 갖는 것이 좋다. 어떤 필드를 선택할 수 있는지, 어떤 종류의 객체를 반환할 수 있는지, 하위 객체에서 사용할 수 있는 필드는 무엇인지, 이것이 바로 스키마가 필요한 이유이다.

GraphQL 서비스는 어떤 언어로든 작성할 수 있다. 하지만 js와같은 특정 언어 문법에 의존 할 수 없기 때문에 간단한 언어를 정의해야한다. 여기서는 GraphQL 스키마 언어(GraphQL schema language) 를 사용할 것이다. 이것은 쿼리 언어와 비슷하며, GraphQL 스키마를 언어에 의존적이지 않은 방식으로 표현할 수 있게 해준다.

GraphQL 스키마의 가장 기본적인 구성 요소는 객체 타입이다. 객체 타입은 쿼리에서 가져올 수 있는 객체의 종류와 그 객체의 필드를 나타낸다. GraphQL 스키마 언어에서는 다음과 같이 표현할 수 있다.

type Character {
  name: String!
  appearsIn: [Episode]!
}
  • Character : 커스텀하게 만든 GraphQL 객체 타입이다. 스키마의 대부분의 타입은 객체 타입이다.

  • name, appearsIn : Character 타입의 필드(속성)이다. GraphQL 내의 쿼리 어디서든 사용할 수 있다,

  • String : 가장 기본의 스칼라(string, number 등 기본 타입)타입이다. 하위 필드를 선택할 수 없고, 특정 값이 반환된다.

  • ! : 필드가 항상 non-nullable 임을 의미한다. 이 필드를 쿼리할 때 GraphQL 서비스가 항상 값을 반환한다.

  • [Episode]! : 필드가 항상 Episode 타입의 배열을 반환한다는 것을 의미한다. Episode 타입은 Character와 같이 또 다른 타입이며, ! 이기 때문에 항상 0개 이상의 아이템을 가진 배열을 반환한다.

여기서 non-nullable(!)에 대한 이해가 필수적이다. 다음과 같이 배열을 기준으로 생각해보자.




스칼라 (Scalar)

GraphQL 객체 타입은 이름과 필드를 가지지만, 어떤 시점에서 이 필드는 구체적인 데이터로 해석되어야한다. 즉, 쿼리의 끝을 나타내고 이를 스칼라라고 부른다.

종류

  • Int: 부호가 있는 32비트 정수.

  • Float: 부호가 있는 부동소수점 값.

  • String: UTF-8 문자열.

  • Boolean: true 또는 false.

  • ID: ID 스칼라 타입은 객체를 다시 요청하거나 캐시의 키로써 자주 사용되는 고유 식별자를 나타낸다.
    ID 타입은 String 과 같은 방법으로 직렬화되지만, ID 로 정의하는 것은 사람이 읽을 수 있도록 하는 의도가 아니라는 것을 의미한다.

대부분의 타입 언어(ts)처럼 GraphQL도 커스텀 스칼라 타입을 만들 수 있다.




타입의 인수

또한 아래처럼 GraphQL 객체 타입의 모든 필드는 0개 이상의 인수를 가질 수 있다.

type Starship {
  id: ID!
  name: String!
  length(unit: LengthUnit = METER): Float
}

모든 인수에는 이름이 있다. 함수가 순서있는 인자를 가져오는 js나 python과 같은 일반적인 언어와는 달리 GraphQL의 모든 인자는 특별한 이름으로 전달된다. 인수는 필수이거나 옵셔널일 수 있다. 인자가 옵셔널일 경우 기본값을 정의할 수 있으며 unit 인자가 전달되지 않으면 METER일 수 있다.





스키마의 타입?

스키마 대부분의 타입은 일반 객체 타입이지만 스키마 내에는 특수한 두 가지 타입이 있다.

schema {
  query: Query
  mutation: Mutation
}

모든 GraphQL 서비스는 query 타입을 가지며 mutation 타입은 가질 수도 있고 가지지 않을 수도 있다.
이러한 타입은 일반 객체 타입과 동일하지만 모든 GraphQL 쿼리의 진입점 (entry point)을 정의하므로 특별하고 볼 수 있다.




열거형 타입

Enums 라고도 하는 열거형 타입은 특정 값들로 제한되는 특별한 종류의 스칼라이다. 타입의 인자가 허용된 값 중 하나임을 검증할 수 있다. 필드가 항상 값의 열거형 집합 중 하나가 될 것임을 타입 시스템을 통해 확인할 수 있다.

아래와 같이 사용하며 스키마에서 Episode 타입을 사용할 때마다 정확히 NEWHOPE, EMPIRE, JEDI 중 하나일 것을 명시한다.

enum Episode {
  NEWHOPE
  EMPIRE
  JEDI
}



Input 타입

mutation으로 생성될 복잡한 객체를 쉽게 전달할 수 있는 기능이다
GraphQL 스키마 언어에서 입력 타입은 일반 객체 타입과 정확히 같지만, type 대신 input이란 키워드를 사용하여 이를 구분한다.

input ReviewInput {
    stars: Int!
    commentary: String   
}



인터페이스 (Interface)

여러 타입 시스템과 마찬가지로 GraphQL도 인터페이스를 지원한다. 인터페이스 는 이를 구현하기 위해 타입이 포함해야하는 특정 필드들을 포함하는 추상 타입이다. 예를 들면, 스타워즈 3부작의 모든 캐릭터들을 표현하는 Character 인터페이스를 가질 수 있다.

interface Character {
    id: ID!								# id는 ID 타입의 값을 가지고, not null이다.
    name: String!						# 이름은 String 타입의 값을 가지고, not null이다.
    friends: [Character]				# 같은 Character의 배열, null일 수 있다.
    appearsIn: [Episode]!				# 어느편에서 출연했는지의 Episode 배열, not null 이다.
}



implements

다른 타입에 implements 키워드로 interface를 이어주면 해당 1interface 인자와 동일한 리턴 타입을 가진 필드를 가져야한다는 것을 의미하고, 여기서 추가 필드를 더 넣어줄 수도 있다.

type Human implements Character {
    id: ID!
    name: String!
    friends: [Character]
    appearsIn: [Episode]!
    starships: [Starship]
    totalCredits: Int
}

인터페이스는 객체나 객체리스트를 반환하려는 경우에 유용하지만, 다양한 다른 타입 유형이 될 수도 있다.

profile
안녕하세요! 26살 프론트엔드 개발자입니다! (2024/03 ~)

0개의 댓글