commonMain.com.apollographql.apollo.api.ApolloResponse.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
The newest version!
package com.apollographql.apollo.api
import com.apollographql.apollo.annotations.ApolloDeprecatedSince
import com.apollographql.apollo.exception.ApolloException
import com.apollographql.apollo.exception.ApolloGraphQLException
import com.apollographql.apollo.exception.DefaultApolloException
import com.apollographql.apollo.exception.NoDataException
import com.benasher44.uuid.Uuid
import kotlin.jvm.JvmField
import kotlin.jvm.JvmName
/**
* Represents a GraphQL response or an exception if no GraphQL response is received.
*
* - [data] contains the parsed data returned in the response
* - [errors] contains any GraphQL errors returned in the response
* - [exception] contains an exception if a GraphQL response wasn't received
*
* GraphQL responses can contain partial data, so it is possible to have both [data] != null and [errors] != null. An [ApolloResponse] may be in any of these states:
* - exception == null && data != null && errors == null: complete data with no errors
* - exception == null && data != null && errors != null: partial data with GraphQL errors
* - exception == null && data == null && errors != null: no data, only GraphQL errors
* - exception == null && data == null && errors == null: no data and no errors - while technically possible, this should not happen with a spec-compliant server
* - exception != null && data == null && errors == null: no GraphQL response was received due to a network error or otherwise
*/
class ApolloResponse
private constructor(
@JvmField
val requestUuid: Uuid,
/**
* The GraphQL operation this response represents
*/
@JvmField
val operation: Operation,
/**
* Parsed response of GraphQL [operation] execution.
* [data] is non-null if some data is received from the server.
* [data] might contain partial data in case of field errors
*
* @see [errors]
* @see [exception]
* @see [dataOrThrow]
*/
@JvmField
val data: D?,
/**
* [GraphQL errors](https://spec.graphql.org/October2021/#sec-Errors) returned by the server to let the client know that something
* has gone wrong.
*
* If no GraphQL error was raised, [errors] is null. Else it's a non-empty list of errors indicating where the error(s) happened.
*
* Note that because GraphQL allows partial data, it is possible to have both [data] non-null and [errors] non-null.
*
* See also [exception]
*/
@JvmField
val errors: List?,
/**
* An [ApolloException] if a GraphQL response wasn't received.
*
* For example, `exception` is non-null in those cases:
* - network failure
* - cache miss
* - parsing error
*
* See also [data]
*/
@JvmField
val exception: ApolloException?,
/**
* Extensions of GraphQL protocol, arbitrary map of key [String] / value [Any] sent by server along with the response.
*/
@JvmField
val extensions: Map,
/**
* The context of GraphQL [operation] execution.
* This can contain additional data contributed by interceptors.
*/
@JvmField
val executionContext: ExecutionContext,
/**
* Indicates that this [ApolloResponse] is the last [ApolloResponse] in a given [Flow] and that no
* other items are expected.
*
* This is used as a hint by the watchers to make sure to subscribe before the last item is emitted.
*
* There can be false negatives where [isLast] is false if the producer does not know in advance if
* other items are emitted.
*
* There must not be false positives. If [isLast] is true, no other items must follow.
*/
@JvmField
val isLast: Boolean,
) {
/**
* A shorthand property to get a non-nullable `data` if handling partial data is **not** important
*/
@get:JvmName("dataAssertNoErrors")
val dataAssertNoErrors: D
get() {
return when {
hasErrors() -> throw ApolloGraphQLException(errors!!.first())
exception != null -> throw DefaultApolloException("An exception happened", exception)
else -> dataOrThrow()
}
}
/**
* Return [data] if not null or throws [NoDataException] else
*/
fun dataOrThrow(): D {
return data ?: throw NoDataException(cause = exception)
}
fun hasErrors(): Boolean = !errors.isNullOrEmpty()
fun newBuilder(): Builder {
return Builder(operation, requestUuid, data, errors, extensions, exception)
.addExecutionContext(executionContext)
.isLast(isLast)
}
class Builder internal constructor(
private val operation: Operation,
private var requestUuid: Uuid,
private var data: D?,
private var errors: List?,
private var extensions: Map?,
private var exception: ApolloException?
) {
private var executionContext: ExecutionContext = ExecutionContext.Empty
private var isLast = false
/**
* Construct a new [Builder] that doesn't contain data, errors nor exception
*
* While possible, this case is probably symptomatic of a buggy GraphQL implementation
* that returned no data while not setting any error
*/
constructor(
operation: Operation,
requestUuid: Uuid,
): this(operation, requestUuid, null, null, null, null)
@Deprecated("Use 2 params constructor instead", ReplaceWith("Builder(operation = operation, requestUuid = requestUuid).data(data = data)"))
@ApolloDeprecatedSince(ApolloDeprecatedSince.Version.v4_0_0)
constructor(
operation: Operation,
requestUuid: Uuid,
data: D?
): this(operation, requestUuid, data, null, null, null)
fun addExecutionContext(executionContext: ExecutionContext) = apply {
this.executionContext = this.executionContext + executionContext
}
fun data(data: D?) = apply {
this.data = data
}
fun errors(errors: List?) = apply {
this.errors = errors
}
fun exception(exception: ApolloException?) = apply {
this.exception = exception
}
fun extensions(extensions: Map?) = apply {
this.extensions = extensions
}
fun requestUuid(requestUuid: Uuid) = apply {
this.requestUuid = requestUuid
}
fun isLast(isLast: Boolean) = apply {
this.isLast = isLast
}
fun build(): ApolloResponse {
return ApolloResponse(
operation = operation,
requestUuid = requestUuid,
data = data,
executionContext = executionContext,
extensions = extensions ?: emptyMap(),
errors = errors,
exception = exception,
isLast = isLast,
)
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy