Last active
January 16, 2024 16:38
-
-
Save sahalnazar/8d874a5afa7d35430e55d08fe02aafc7 to your computer and use it in GitHub Desktop.
GraphQL request handler helper class for Apollo Client in Kotlin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.apollographql.apollo3.ApolloClient | |
import com.apollographql.apollo3.api.ApolloResponse | |
import com.apollographql.apollo3.api.Mutation | |
import com.apollographql.apollo3.api.Operation | |
import com.apollographql.apollo3.api.Query | |
import com.apollographql.apollo3.exception.ApolloException | |
import timber.log.Timber | |
/** | |
* This class handles the execution of GraphQL queries and mutations using the Apollo client. | |
* It provides a mechanism to perform queries and mutations and map the responses to structured results. | |
* | |
* @param apolloClient The Apollo client instance used for making GraphQL requests. | |
*/ | |
class ApolloRequestHandler(private val apolloClient: ApolloClient) { | |
/** | |
* Execute a GraphQL query and return a structured result. | |
* | |
* @param query The GraphQL query to execute. | |
* @param mapper The mapper function that converts the query response to a structured result. | |
* @return A MyResult containing the structured result or an error. | |
*/ | |
suspend fun <T : Query.Data, R> execute(query: Query<T>, mapper: (T?) -> R): ApiResponse<R> { | |
return try { | |
val response = apolloClient.query(query).execute() | |
if (response.hasErrors()) { | |
Timber.e(response.errors?.toString()) | |
ApiResponse.Error(response.toErrorList()) | |
} else { | |
Timber.d(response.data.toString()) | |
ApiResponse.Success(mapper(response.data)) | |
} | |
} catch (e: ApolloException) { | |
Timber.e(e.message) | |
ApiResponse.Error(e.toErrorList()) | |
} | |
} | |
/** | |
* Execute a GraphQL mutation and return a structured result. | |
* | |
* @param mutation The GraphQL mutation to execute. | |
* @param mapper The mapper function that converts the mutation response to a structured result. | |
* @return A MyResult containing the structured result or an error. | |
*/ | |
suspend fun <T : Mutation.Data, R> execute(mutation: Mutation<T>, mapper: (T?) -> R): ApiResponse<R> { | |
return try { | |
val response = apolloClient.mutation(mutation).execute() | |
if (response.hasErrors()) { | |
Timber.e(response.errors?.toString()) | |
ApiResponse.Error(response.toErrorList()) | |
} else { | |
Timber.d(response.data.toString()) | |
ApiResponse.Success(mapper(response.data)) | |
} | |
} catch (e: ApolloException) { | |
Timber.e(e.message) | |
ApiResponse.Error(e.toErrorList()) | |
} | |
} | |
// Convert ApolloResponse errors to a list of error messages | |
private fun <T : Operation.Data> ApolloResponse<T>.toErrorList() = | |
errors?.map { it.message }.orEmpty() | |
// Convert ApolloException to a list containing the exception message | |
private fun ApolloException.toErrorList() = | |
this.message?.let { listOf(it) } ?: emptyList() | |
} | |
// Sealed class to represent structured result of GraphQL requests | |
sealed class ApiResponse<out T> { | |
// Represents success with non-nullable data | |
data class Success<out T>(val data: T) : ApiResponse<T>() | |
// Represents errors with a list of error messages | |
data class Error(val errors: List<String>) : ApiResponse<Nothing>() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment