GraphQL 에서는 다양한 스칼라 타입 (단 하나의 값만을 저장할 수 있는 데이터 타입) 을 주고받을 수 있는데, 스칼라 타입은 우리가 알고 있는 기본적인 자료형을 지원할 뿐만 아니라, 서버 개발자가 직접 정의한 커스텀 스칼라 타입 또한 주고받을 수 있다.
GraphQL 에 내장되어 있는 기본 스칼라 타입은 이러한 것들이 있다.
Int
: 부호가 있는 32비트 정수Float
: 부호가 있는 부동소수점 값String
: UTF-8 문자열Boolean
: true
또는 false
아래는 URL
이라는 커스텀 타입이 정의되어 있는 경우이다. 누구나 알다시피, 이 URL
타입이 갖고있는 값은 String
타입으로 매핑될 수 있다. 어차피 https://velog.io/@haero_kim 와 같은 모양일테니까.
커스텀 스칼라 타입을 정의하면, 해당 값이 어떤 역할을 하는 값인지에 대해 깔끔하게 명시할 수 있어 편리하다는 장점이 있다.
안드로이드용 Apollo-Client 는 다양한 쿼리, 뮤테이션에 사용되는 스칼라 타입들에 대해 자동으로 Kotlin
의 자료형에 적절히 대응 (매핑) 해준다. 예를 들어 이런 상황이다.
GraphQL 의 내장 스칼라 타입인 String
을 Kotlin 의 kotlin.String
으로 어댑팅하여 코틀린의 String
타입으로 자유 분방하게 사용할 수 있는 것이다.
하지만, 위에서 살펴봤던 예시인 URL
이라는 커스텀 타입은 어떨까? Apollo-Client 는 이 타입을 Kotlin 의 어떤 자료형에 매핑해야 할지 알 길이 없다. 따라서 이럴 경우 Any
로 컴파일 되게 된다.
Any
타입은 코틀린 최상위 클래스이기 때문에, 이를 적절히 활용할 방안이 없다. 그냥 데이터가 유실된 것과 다름 없다. 따라서 우리는 GraphQL 의 커스텀 스칼라 타입을 코틀린의 어떤 타입으로 직렬화 할 지에 대해 따로 정의해주어야 한다.
Apollo-Client 에서는 이러한 것 역시 편리하게 구현할 수 있다.
커스텀 스칼라 타입을 코틀린의 클래스로 매핑하기 위해, Custom Type Adapter 라는 것을 활용할 수 있다. 이번 예시에서는 URL
이라는 커스텀 타입을 예로 들겠다.
URL
타입을 코틀린의 String
타입으로 변환해보기
먼저, app
단위의 build.gradle
에서 아래와 같이 설정해준다.
apollo {
generateKotlinModels = true
customTypeMapping = [
"URL" : "kotlin.String"
]
}
이렇게 하면 URL
이라는 녀석을 kotlin.String
클래스에 매핑하겠다는 의미이다.
그 다음 아래와 같이 Custom Type Adapter 를 정의해주자.
decode()
와 encode()
메소드를 통해 커스텀 타입을 어떻게 해석하고, 어떻게 다시 GraphQL 커스텀 스칼라 타입으로 변환할 지에 대해 정의해주는 것이다.
val urlTypeAdapter = object : CustomTypeAdapter<String> {
override fun decode(value: CustomTypeValue<*>): String {
return try {
value.value.toString()
} catch (e: ParseException) {
throw RuntimeException(e)
}
}
override fun encode(value: String): CustomTypeValue<*> {
return CustomTypeValue.GraphQLString(value)
}
}
이제 우리가 만든 어댑터를, ApolloClient
객체에 붙여주기만 하면 된다.
addCustomTypeAdapter()
를 통해 '어떤 커스텀 타입에 대한 어댑터인지'와 우리가 정의한 어댑터를 넘겨주게 되면 정상적으로 등록된다.
참고로 CustomType
은 이전에 다운받은 스키마 파일을 기반으로 자동으로 생성되는 enum
클래스이므로 걱정하지 않아도 된다.
val apolloClient: ApolloClient = ApolloClient.builder()
.serverUrl(serverBaseUrl)
.addCustomTypeAdapter(CustomType.URL, urlTypeAdapter)
.build()
이후 Rebuild 를 한 번 돌리게 되면, URL
타입은 kotlin.String
타입으로 매핑되어, 친숙한 String
형태로 자유자재로 사용할 수 있다.
다음 포스팅에선 파일을 업로드하는 방법에 대해 알아보고자 한다.