Home Parameterizing GraphQL fields with graphql-kotlin
Post
Cancel

Parameterizing GraphQL fields with graphql-kotlin

This article serves as a companion to the video posted above.

The goal is to create a parameterized field on a [GraphQL][https://graphql.org/] schema, using graphql-kotlin.

Code found here

Boilerplate

The full source code for the project can be found on github. A boilerplate to get started can be found at this commit

Altair

I like to use the Altair firefox plugin (also available for Chrome) to develop GraphQL schemas. Check it out, maybe donate.

Adding an image to the schema.

The initial ImageQueryService is quite simple. Returning a Image object initialized with strings.

1
2
3
4
5
6
7
8
// ImageQueryService.kt
package com.rharriso

data class Image(val title: String, val url: String)

class ImageQueryService {
    fun fetchImage() = Image(title = "Zugspitze at Sunrise", url = "static/zugspitze-sunrise-original.jpg")
}

This is then exposed through the GraphqlHandler as.

1
2
3
4
5
6
7
8
9
10
11
 class GraphQLHandler {
     companion object {
-        private val config = SchemaGeneratorConfig(supportedPackages = listOf("nyc.rowan"))
+        private val config = SchemaGeneratorConfig(supportedPackages = listOf("com.rharriso"))
         private val queries = listOf(
-                TopLevelObject(HelloQueryService())
+                TopLevelObject(HelloQueryService()),
+                TopLevelObject(ImageQueryService())
         )

         private val mutations: List<TopLevelObject> = listOf()

This can then be queried as follows:

1
2
3
4
5
6
query {
  fetchImage {
    url
    title
  }
}

Parameterizing the property with a string

Simply adding an argument to the fetch image function will expose the argument to the schema.

1
2
3
4
5
6
7
8
9
10
11
12
13
 data class Image(val title: String, val url: String)

 class ImageQueryService {
-    fun fetchImage() = Image(title = "Zugspitze at Sunrise", url = "static/zugspitze-sunrise-original.jpg")
+    fun fetchImage(imageSize: String?): Image {
+        val imageSizeUsed = imageSize ?: "original"
+
+        return Image(
+                title = "Zugspitze at Sunrise",
+                url = "static/zugspitze-sunrise-$imageSizeUsed.jpg"
+        )
+    }
 }

The argument can now be used in the query as follows.

1
2
3
4
5
6
query ($imageSize: String){
  fetchImage (imageSize: $imageSize){
    url
    title
  }
}

Parameterizing with an enum

Parameterizing with a string allows us to query different image URLs, but it doesn’t limit us to valid image URLs. For example if "notarealimage" was requested, then we’d received, a URL that would return 404.

An improvement would use an enum to parameterize the image. This can be done by changing the type of the arguments in the Kotlin query service.

1
2
3
4
5
6
7
8
9
10
11
 data class Image(val title: String, val url: String)

+enum class ImageSize { original, small, }
+
 class ImageQueryService {
-    fun fetchImage(imageSize: String?): Image {
-        val imageSizeUsed = imageSize ?: "original"
+    fun fetchImage(imageSize: ImageSize?): Image {
+        val imageSizeUsed = imageSize ?: ImageSize.original

         return Image(

Now if we try to request an invalid size, we’ll receive an error. Better yet, if we are generating types on the client. Then we will receive a compiler error when trying to using an invalid parameter.

Conclusion

Parameterizing fields can make them more flexible. However, being smart about the type used to parameterize them can help avoid missing data or invalid responses.

-->