GraphQL на Kotlin: Полный обзор библиотек и инструментов
GraphQL — это язык запросов для API и среда выполнения для выполнения этих запросов с вашими существующими данными. Он предоставляет клиентам возможность запрашивать именно те данные, которые им нужны, что делает его мощной альтернативой REST. В экосистеме Kotlin существует несколько зрелых библиотек для создания серверной части GraphQL. В этой статье мы подробно разберем основные инструменты, их синтаксис и примеры использования.
Почему Kotlin для GraphQL?
Kotlin, будучи статически типизированным языком, работающим на JVM, отлично подходит для построения типобезопасных GraphQL-схем. Компилятор Kotlin помогает избежать ошибок на этапе написания кода, а выразительный синтаксис делает код чистым и лаконичным. Основные библиотеки для работы с GraphQL в Kotlin включают:
- graphql-kotlin (от Expedia Group) — наиболее популярная библиотека, тесно интегрируемая со Spring Boot.
- KGraphQL — альтернатива с акцентом на простую конфигурацию и минималистичный API.
- Apollo Kotlin — клиентская библиотека для Android и KMP, но также предоставляет серверные возможности.
Библиотека graphql-kotlin
graphql-kotlin — это набор библиотек для построения серверов GraphQL на Kotlin. Основной подход — использование аннотаций и data-классов для автоматической генерации схемы.
Установка
Добавьте зависимость в build.gradle.kts:
dependencies {
implementation("com.expediagroup:graphql-kotlin-spring-server:7.0.0")
implementation("com.expediagroup:graphql-kotlin-schema-generator:7.0.0")
}
Пример: Простой запрос
Определим data-класс и ресолвер:
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 {
// Имитация получения из БД
return User(id = id, name = "Alice", email = "alice@example.com")
}
}
graphql-kotlin автоматически сгенерирует схему. Теперь клиент может выполнить запрос:
query {
getUser(id: 1) {
name
email
}
}
Ответ будет содержать только запрошенные поля:
{
"data": {
"getUser": {
"name": "Alice",
"email": "alice@example.com"
}
}
}
Мутации (изменение данных)
Для мутаций используется интерфейс Mutation:
import com.expediagroup.graphql.server.operations.Mutation
class UserMutation : Mutation {
fun createUser(name: String, email: String): User {
// Логика создания пользователя
return User(id = 2, name = name, email = email)
}
}
Соответствующий запрос:
mutation {
createUser(name: "Bob", email: "bob@example.com") {
id
name
}
}
Библиотека KGraphQL
KGraphQL предлагает более DSL-ориентированный подход, без необходимости в аннотациях. Схема строится программно.
Установка
dependencies {
implementation("com.apurebase:kgraphql:0.18.0")
implementation("com.apurebase:kgraphql-ktor:0.18.0") // для Ktor
}
Пример: Определение схемы
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)
}
}
}
Затем подключаем к веб-фреймворку (Ktor, Spring и т.д.):
embeddedServer(Netty, port = 8080) {
routing {
post("/graphql") {
call.respond(schema.execute(call.receiveText()))
}
}
}.start(wait = true)
Типы и интерфейсы в схеме GraphQL
Обе библиотеки поддерживают сложные типы: интерфейсы, union-типы, enumы. Рассмотрим пример с интерфейсом для graphql-kotlin:
interface Character {
val id: Int
val name: String
}
data class Human(
override val id: Int,
override val name