.graphql file
In this section, we will learn more about GraphQL Queries and integrate with the android app UI.
Create .graphql files with your queries or mutations
Apollo android generates code from queries and mutations contained in .graphql
files in your target. Let's define a graphql query to fetch the required data. We define all our queries and mutations in api.graphql
file.
Create a new file at the graphql folder api.graphql
and add the following code:
+ query getMyTodos {+ todos(where: { is_public: { _eq: false} }, order_by: { created_at: desc }) {+ id+ title+ created_at+ is_completed+ }
We have now written the graphql query that will be converted to a class by apollo codegen that you can use inside your view controller files. Try building your project, there will bunch of code generated for you by apollo.
What does this query do?
The query fetches todos
with a simple condition; is_public
must be false. We sort the todos descending by its created_at
time according to the schema. We specify which fields we need for the todos node.
The query is now ready, let's integrate it with our android code, open TaskFragment.kt
import com.apollographql.apollo.ApolloCallimport com.apollographql.apollo.api.Responseimport com.apollographql.apollo.exception.ApolloExceptionimport com.apollographql.apollo.fetcher.ApolloResponseFetchers
also define the query variable which will use the class generated by apollo,
+ private lateinit var getMyTodosQuery: GetMyTodosQuery
Now at the bottom of the file, add this,
// Queries & Mutationsprivate fun getMyTodoQueryCloud() {// Init QuerygetMyTodosQuery = GetMyTodosQuery.builder().build()// Apollo runs query on background threadNetwork.apolloClient.query(getMyTodosQuery)?.enqueue(object : ApolloCall.Callback<GetMyTodosQuery.Data>() {override fun onFailure(error: ApolloException) {Log.d("Todo", error.toString() )}override fun onResponse(@NotNull response: Response<GetMyTodosQuery.Data>) {// Changing UI must be on UI threadLog.d("Todo", response.data().toString() )}})}
We are using the static apolloClient that we created in our network class so, we have the access to same instance everywhere. Let's log the response for now and initialize the query oncreate of the fragment,
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)arguments?.let {completeStatus = it.getString(COMPLETE_STATUS)}+ // Get Initial Todos from cloud+ getMyTodoQueryCloud()}
Let's remove the mock todos
data which was used to populate sample data.
var listItems: MutableList<Task> = mutableListOf(- Task(1, "Private Task", false),- Task(2, "Private Task 1", false),- Task(3, "Private Task 2", false),- Task(4, "Private Task 3", false),- Task(5, "Private Task 4", true),- Task(6, "Private Task 5", false))
Woot! You have written your first GraphQL integration with android. Easy isn't it?
How does this work?
When you execute apolloClient.query
, Apollo will give callback on its execution,
onFailure
: A runtime error with graphQLErrors and networkError properties. Contains information about what went wrong with your query.
onResponse
: An object (response.data()
) containing the result of your GraphQL query. This will contain our actual data from the server. In our case, it will be the todo data.
You can read more about response format and error handling here
Using the data()
object, we are parsing the results from the server. In our query, data()
object has an array todos
which can be mapped to render our RecyclerView
in our fragment.
Lets plug this with the list, add below in the OnResponse callback
override fun onResponse(response: Response<GetMyTodosQuery.Data>) {// Changing UI must be on UI threadLog.d("Todo", response.data().toString() )+ listItems = response.data()?.todos()?.toMutableList()+ activity?.runOnUiThread { updateTabs() }}
If you noted, there has been some client side filtering to the todos that are displayed.
- Build apps and APIs 10x faster
- Built-in authorization and caching
- 8x more performant than hand-rolled APIs