Integrating GraphQL in Compose Multiplatform project

GraphQL is a data query and manipulation language. It is server-side runtime for application programming interfaces (APIs) that allows specifying what data is to be retrieved or modified. GraphQL is neither frontend nor backend, it is a language spoken between two to exchange information.
GraphQL is not SQL as it uses resolver to retrieve or manipulate the data. GraphQL offers more flexible and efficient way of API development. Unlike REST, it has only 1 endpoint and data is handled by defining “query” and “mutation” in its schema. For more information you can refer : https://graphql.org/
For this sample app, we will use Apollo GraphQL open API: https://studio.apollographql.com/public/countries/variant/current/schema/reference
This page shows schema which will give us idea what kind of data we can get from this API.
For example, if want to get continents details. Query will be:
query ExampleQuery {
continents {
code
name
countries {
name
}
}
}
Here query can be modified to get any one of the attribute, for example.
query ExampleQuery {
continents {
name
}
}
Similarly if we want to fetch all details of countries, query will be:
query Countries {
countries {
code
name
native
phone
continent {
code
name
}
currency
languages {
rtl
native
name
code
}
emoji
emojiU
states {
code
name
}
}
}
We can even try to execute this query in explorer to see results. https://studio.apollographql.com/public/countries/variant/current/explorer
Let’s open build.gradle.kts of shared module to add plugin.
// Add in libs.versions.toml
graphql = "4.0.1"
apolloGraphQl = { id = "com.apollographql.apollo", version.ref = "graphql" }
// Add
plugins {
....
alias(libs.plugins.apolloGraphQl)
}
apollo {
service("service") {
packageName.set("com.your.package.name")
}
}
Now we have to download graphql schema by following command. Don’t forget to change the correct package.
./gradlew shared:downloadApolloSchema --endpoint='https://countries.trevorblades.com/graphql' --schema="shared/src/commonMain/graphql/com/khareab/cmp/graphql"
Once executed we will get schema file “graphql.graphqls” under mentioned package. Now sync the project
Inside same package we will create 2 queries file. One for fetching Country list and another country details.
// For country list
query Countries {
countries {
name
capital
code
emoji
}
}
// For country details
query Country($country_code: ID!) {
country(code: $country_code) {
name
capital
code
emoji
currency
languages {
name
}
continent {
name
}
}
}
Create Apollo client.
val apolloClient = ApolloClient
.Builder()
.serverUrl("https://countries.trevorblades.com/graphql")
.build()
Now we can access data using client and query created in previous steps.
apolloClient
.query(CountriesQuery())
.execute()
.data
?.countries
?: emptyList()
Once this is configured, we can use the fetched data to show on UI. We can create simple UI in composeApp->commonMain/
Box(modifier = Modifier.fillMaxSize()) {
if (state.isLoading) {
// Loading indicator
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
} else {
// List of countries
LazyColumn(
modifier = Modifier.fillMaxSize()
) {
items(state.countries.size) { index ->
// Country Item
CountryItem(
country = state.countries[index],
index = index
) {
onSelectedCountry(state.countries[index].code)
}
}
}
GetScrollBars()
}
}
Now use View Model to call GraphQL api client which we created in previous steps.
You can also follow the sample project I uploaded on Github. This uses clean architecture where it is divided in data, domain and UI layer.
Apollo client resides in data layer which gives fetched data to usecases in domain layer. Domain layer converts the data into domain model as well as apply sort operation (business logic). Response is then delivered to ViewModel in UI layer through which data is displayed on UI using compose state. You can find repository like at:
Clone the project and then sync it. And then try to run it on different platforms.

That’s all, happy coding.