KNET oferuje wbudowaną obsługę GraphQL z DSL query builder i pełnym wsparciem dla mutations.
import rip.nerd.kitsunenet.graphql.KNETGraphQL
val graphql = KNETGraphQL("https://api.example.com/graphql")
// Proste query
val result = graphql.query("""
query {
users {
id
name
email
}
}
""")
val users = result.data["users"]
val result = graphql.query(
query = """
query GetUser(${'$'}id: ID!) {
user(id: ${'$'}id) {
id
name
email
posts {
title
}
}
}
""",
variables = mapOf("id" to "123")
)
val user = result.data["user"] as Map<*, *>
println(user["name"])
val result = graphql.mutation(
mutation = """
mutation CreateUser(${'$'}input: CreateUserInput!) {
createUser(input: ${'$'}input) {
id
name
email
}
}
""",
variables = mapOf(
"input" to mapOf(
"name" to "Jan Kowalski",
"email" to "jan@example.com",
"password" to "secret123"
)
)
)
if (result.hasErrors) {
result.errors.forEach { error ->
println("Error: ${error.message}")
}
} else {
val newUser = result.data["createUser"]
println("Created user: $newUser")
}
val query = graphqlQuery {
operation("GetUsers") {
field("users") {
args("limit" to 10, "offset" to 0)
field("id")
field("name")
field("email")
field("profile") {
field("avatar")
field("bio")
}
field("posts") {
args("status" to "PUBLISHED")
field("id")
field("title")
field("createdAt")
}
}
}
}
val result = graphql.execute(query)
val mutation = graphqlMutation {
operation("CreatePost") {
variables {
variable("input", "CreatePostInput!")
}
field("createPost") {
args("input" to "\$input")
field("id")
field("title")
field("slug")
field("author") {
field("name")
}
}
}
}
val result = graphql.execute(mutation, mapOf(
"input" to mapOf(
"title" to "My Post",
"content" to "Content here..."
)
))
val query = graphqlQuery {
fragment("UserFields", "User") {
field("id")
field("name")
field("email")
}
operation("GetUsersAndMe") {
field("users") {
spread("UserFields")
}
field("me") {
spread("UserFields")
field("role") // Dodatkowe pole
}
}
}
val result = graphql.query(myQuery)
when {
result.hasErrors && result.data == null -> {
// Błąd krytyczny - brak danych
result.errors.forEach { error ->
Log.e("GraphQL", "Error: ${error.message}")
Log.e("GraphQL", "Path: ${error.path}")
Log.e("GraphQL", "Locations: ${error.locations}")
}
showError("Nie można pobrać danych")
}
result.hasErrors && result.data != null -> {
// Częściowe dane z błędami
Log.w("GraphQL", "Partial errors: ${result.errors}")
processPartialData(result.data!!)
}
else -> {
// Sukces
processData(result.data!!)
}
}
data class UsersResponse(
val users: List<User>
)
data class User(
val id: String,
val name: String,
val email: String
)
val result = graphql.query<UsersResponse>("""
query {
users {
id
name
email
}
}
""")
result.data?.users?.forEach { user ->
println("${user.id}: ${user.name}")
}
val graphql = KNETGraphQL.builder("https://api.example.com/graphql")
.headers(mapOf(
"Authorization" to "Bearer $token",
"X-Client-Version" to "1.0.0"
))
.timeout(30_000)
.interceptor { request, chain ->
// Custom logic
chain(request)
}
.onError { errors ->
// Global error handling
analytics.logGraphQLErrors(errors)
}
.build()
// Batch multiple queries
val results = graphql.batch(
graphqlQuery { field("users") { field("id"); field("name") } },
graphqlQuery { field("posts") { field("id"); field("title") } },
graphqlQuery { field("me") { field("id"); field("email") } }
)
val users = results[0].data["users"]
val posts = results[1].data["posts"]
val me = results[2].data["me"]
class UserRepository(private val graphql: KNETGraphQL) {
suspend fun getUsers(limit: Int = 20): List<User> {
val result = graphql.query(
"""
query GetUsers(${'$'}limit: Int!) {
users(limit: ${'$'}limit) {
id
name
email
avatar
}
}
""",
mapOf("limit" to limit)
)
return result.data?.let {
(it["users"] as List<*>).map { userData ->
User.fromMap(userData as Map<*, *>)
}
} ?: emptyList()
}
suspend fun createUser(name: String, email: String): User? {
val result = graphql.mutation(
"""
mutation CreateUser(${'$'}name: String!, ${'$'}email: String!) {
createUser(name: ${'$'}name, email: ${'$'}email) {
id
name
email
}
}
""",
mapOf("name" to name, "email" to email)
)
return result.data?.let {
User.fromMap(it["createUser"] as Map<*, *>)
}
}
}