commonMain.com.apollographql.apollo3.api.internal.ResponseParser.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apollo-api-jvm Show documentation
Show all versions of apollo-api-jvm Show documentation
Apollo GraphQL API classes
package com.apollographql.apollo3.api.internal
import com.apollographql.apollo3.api.ApolloResponse
import com.apollographql.apollo3.api.CustomScalarAdapters
import com.apollographql.apollo3.api.DeferredFragmentIdentifier
import com.apollographql.apollo3.api.Error
import com.apollographql.apollo3.api.Operation
import com.apollographql.apollo3.api.falseVariables
import com.apollographql.apollo3.api.json.JsonReader
import com.apollographql.apollo3.api.json.MapJsonReader
import com.apollographql.apollo3.api.json.readAny
import com.apollographql.apollo3.api.parseData
import com.benasher44.uuid.Uuid
import com.benasher44.uuid.uuid4
/**
* [ResponseParser] parses network responses, including data, errors and extensions from a [JsonReader]
*/
internal object ResponseParser {
fun parse(
jsonReader: JsonReader,
operation: Operation,
requestUuid: Uuid?,
customScalarAdapters: CustomScalarAdapters,
deferredFragmentIds: Set?,
): ApolloResponse {
jsonReader.beginObject()
var data: D? = null
var errors: List? = null
var extensions: Map? = null
while (jsonReader.hasNext()) {
@Suppress("UNCHECKED_CAST")
when (jsonReader.nextName()) {
"data" -> {
val falseVariables = operation.falseVariables(customScalarAdapters)
data = operation.parseData(jsonReader, customScalarAdapters, falseVariables, deferredFragmentIds, errors)
}
"errors" -> errors = jsonReader.readErrors()
"extensions" -> extensions = jsonReader.readAny() as? Map
else -> jsonReader.skipValue()
}
}
jsonReader.endObject()
return ApolloResponse.Builder(operation = operation, requestUuid = requestUuid ?: uuid4())
.errors(errors)
.data(data)
.extensions(extensions)
.build()
}
fun parseError(
payload: Map,
) = MapJsonReader(payload).readError()
private fun JsonReader.readErrors(): List {
if (peek() == JsonReader.Token.NULL) {
nextNull()
return emptyList()
}
beginArray()
val list = mutableListOf()
while (hasNext()) {
list.add(readError())
}
endArray()
return list
}
@Suppress("UNCHECKED_CAST")
private fun JsonReader.readError(): Error {
var message = ""
var locations: List? = null
var path: List? = null
var extensions: Map? = null
var nonStandardFields: MutableMap? = null
beginObject()
while (hasNext()) {
when (val name = nextName()) {
"message" -> message = nextString() ?: ""
"locations" -> {
locations = readErrorLocations()
}
"path" -> {
path = readPath()
}
"extensions" -> {
extensions = readAny() as? Map?
}
else -> {
if (nonStandardFields == null) nonStandardFields = mutableMapOf()
nonStandardFields[name] = readAny()
}
}
}
endObject()
@Suppress("DEPRECATION")
return Error(message, locations, path, extensions, nonStandardFields)
}
private fun JsonReader.readPath(): List? {
if (peek() == JsonReader.Token.NULL) {
return nextNull()
}
val list = mutableListOf()
beginArray()
while (hasNext()) {
when (peek()) {
JsonReader.Token.NUMBER, JsonReader.Token.LONG -> list.add(nextInt())
else -> list.add(nextString()!!)
}
}
endArray()
return list
}
private fun JsonReader.readErrorLocations(): List? {
if (peek() == JsonReader.Token.NULL) {
return nextNull()
}
val list = mutableListOf()
beginArray()
while (hasNext()) {
list.add(readErrorLocation())
}
endArray()
return list
}
private fun JsonReader.readErrorLocation(): Error.Location {
var line: Int = -1
var column: Int = -1
beginObject()
while (hasNext()) {
when (nextName()) {
"line" -> line = nextInt()
"column" -> column = nextInt()
else -> skipValue()
}
}
endObject()
return Error.Location(line, column)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy