GraphQL on Kotlin: A Complete Overview of Libraries and Tools
GraphQL is a query language for APIs and a runtime for executing those queries with your existing data. It allows clients to request exactly the data they need, making it a powerful alternative to REST. In the Kotlin ecosystem, there are several mature libraries for building a GraphQL backend. In this article, we will take a detailed look at the main tools, their syntax, and usage examples.
Why Kotlin for GraphQL?
Kotlin, being a statically typed language running on the JVM, is an excellent fit for building type-safe GraphQL schemas. The Kotlin compiler helps avoid errors at the code-writing stage, and its expressive syntax makes the code clean and concise. The main libraries for working with GraphQL in Kotlin include:
- graphql-kotlin (from Expedia Group) — the most popular library, tightly integrated with Spring Boot.
- KGraphQL — an alternative focusing on simple configuration and a minimalistic API.
- Apollo Kotlin — a client library for Android and KMP, but also provides server-side capabilities.
The graphql-kotlin Library
graphql-kotlin is a set of libraries for building GraphQL servers in Kotlin. The main approach is using annotations and data classes for automatic schema generation.
Installation
Add the dependency to build.gradle.kts:
dependencies { implementation("com.expediagroup:graphql-kotlin-spring-server:7.0.0") implementation("com.expediagroup:graphql-kotlin-schema-generator:7.0.0")}Example: A Simple Query
Define a data class and a resolver:
import com.expediagroup.graphql.server.operations.Query
data class User(val id: Int, val name: String, val email: String)
class UserQuery : Query { fun getUser(id: Int): User { // Simulating fetching from a database return User(id = id, name = "Alice", email = "alice@example.com") }}graphql-kotlin will automatically generate the schema. Now the client can execute a query:
query { getUser(id: 1) { name email }}The response will contain only the requested fields:
{ "data": { "getUser": { "name": "Alice", "email": "alice@example.com" } }}Mutations (Modifying Data)
For mutations, the Mutation interface is used:
import com.expediagroup.graphql.server.operations.Mutation
class UserMutation : Mutation { fun createUser(name: String, email: String): User { // User creation logic return User(id = 2, name = name, email = email) }}The corresponding query:
mutation { createUser(name: "Bob", email: "bob@example.com") { id name }}The KGraphQL Library
KGraphQL offers a more DSL-oriented approach, without the need for annotations. The schema is built programmatically.
Installation
dependencies { implementation("com.apurebase:kgraphql:0.18.0") implementation("com.apurebase:kgraphql-ktor:0.18.0") // for Ktor}Example: Defining a Schema
import com.apurebase.kgraphql.schema.dsl.SchemaBuilder
val schema = SchemaBuilder { query("hello") { resolver { -> "Hello, World!" } }
query("user") { resolver { id: Int -> User(id = id, name = "Charlie", email = "charlie@example.com") } }
mutation("createUser") { resolver { name: String, email: String -> User(id = 3, name = name, email = email) } }}Then connect it to a web framework