GraphQL Document wrapper generator for Kotlin Multiplatform Project.
Currently available for JVM/Android/iOS
kgql core classes
kgql Gradle Plugin generates wrapper classes for provided GraphQL document files.
kgql requires Gradle 5.3.1 or later
Supported GraphQL file extension: .gql
or .graphql
buildScript {
repositories {
jcenter()
maven { url "https://dl.bintray.com/yshrsmz/kgql" }
}
dependencies {
classpath 'com.codingfeline.kgql:gradle-plugin:0.4.0'
}
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'com.codingfeline.kgql'
repositories {
maven { url "https://dl.bintray.com/yshrsmz/kgql" }
}
kgql {
packageName = "com.sample"
sourceSet = files("src/main/kgql")
typeMapper = [
// mapper for non-scalar type
"UserProfile": "com.sample.data.UserProfile"
]
}
buildScript {
repositories {
jcenter()
maven { url "https://dl.bintray.com/yshrsmz/kgql" }
}
dependencies {
classpath 'com.codingfeline.kgql:gradle-plugin:0.4.0'
}
}
apply plugin: 'kotlin-multiplatform'
apply plugin: 'com.codingfeline.kgql'
repositories {
maven { url "https://dl.bintray.com/yshrsmz/kgql" }
}
kgql {
packageName = "com.sample"
sourceSet = files("src/main/kgql")
typeMapper = [
// mapper for non-scalar type
"UserProfile": "com.sample.data.UserProfile"
]
}
When you apply kgql plugin, generateKgqlInterface
task is added to the project. Manually executing it is one way, but the task is integrated into project's build task, so it will be generated upon each build.
ktor extensions for kgql
# viewer.gql
query {
viewer {
login
}
}
Below code will be generated from above GraphQL document file(viewer.gql).
package com.sample
import com.codingfeline.kgql.core.KgqlRequestBody
import kotlin.String
import kotlin.Unit
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Optional
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.UnstableDefault
import kotlinx.serialization.json.Json
object ViewerDocument {
private val document: String = """
|query {
| viewer {
| login
| }
|}
|""".trimMargin()
@UnstableDefault
object Query {
/**
* Generate Json string of [Request]
*/
fun requestBody(json: Json = Json.plain): String = json.stringify(serializer(), Request())
fun serializer(): KSerializer<Request> = Request.serializer()
@Serializable
data class Request(
@SerialName(value = "variables") @Optional override val variables: Unit? = null,
@Optional @SerialName(value = "operationName") override val operationName: String? =
null,
@SerialName(value = "query") override val query: String = document
) : KgqlRequestBody<Unit>
}
}
You can use this code with Ktor or any other HttpClient.
Example usage with Ktor is below
package com.sample
import com.codingfeline.kgql.core.KgqlResponse
import com.codingfeline.kgql.core.KgqlError
import com.sample.ViewerDocument
import io.ktor.client.HttpClient
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.request.headers
import io.ktor.client.request.post
import io.ktor.http.ContentType
import io.ktor.http.content.TextContent
import io.ktor.http.Url
import kotlinx.serialization.json.JSON
import kotlinx.serialization.Serializable
const val TOKEN = "YOUR_GITHUB_TOKEN"
@Serializable
data class ViewerWrapper(
val viewer: Viewer
)
@Serializable
data class Viewer(
val login: String
)
@Serializable
data class ViewerResponse(
override val data: ViewerWrapper?,
override val errors: List<KgqlError>?
): KgqlResponse<ViewerWrapper>
class GitHubApi {
private val client = HttpClient {
install(JsonFeature)
}
suspend fun fetchLogin(): Viewer? {
val response = client.post<String>(url = Url("https://api.github.com/graphql")) {
body = TextContent(text = ViewerDocument.Query.requestBody(), contentType = ContentType.Application.Json)
headers {
append("Authorization", "bearer $TOKEN")
}
}
val res = JSON.parse(ViewerResponse.serializer(), response)
return res.data?.viewer
}
}
This library is highly inspired by squareup/sqldelight and the gradle plugin and basic idea is heavily based on it. Thanks for this.