NASA Explorer uses Retrofit to communicate with the NASA APOD (Astronomy Picture of the Day) API. Retrofit is a type-safe HTTP client that makes it easy to consume RESTful web services by converting API interfaces into callable Kotlin functions.
Retrofit turns your HTTP API into a Java/Kotlin interface, providing compile-time validation of API requests and automatic serialization/deserialization.
Define API endpoints as Kotlin interface methods with Retrofit annotations:
NasaApiService.kt
package com.ccandeladev.nasaexplorer.data.apiimport retrofit2.http.GETimport retrofit2.http.Queryinterface NasaApiService { // Get image of the day (optionally for a specific date) @GET("planetary/apod") suspend fun getImageOfTheDay( @Query("api_key") apiKey: String, @Query("date") date: String? = null ): NasaResponse // Get images in a date range @GET("planetary/apod") suspend fun getImagesInRange( @Query("api_key") apiKey: String, @Query("start_date") startDate: String, @Query("end_date") endDate: String? = null ): List<NasaResponse> // Get random images @GET("planetary/apod") suspend fun getRandomImages( @Query("api_key") apiKey: String, @Query("count") count: Int, ): List<NasaResponse>}
The suspend keyword makes these functions work with Kotlin coroutines, allowing async network calls without blocking threads.
API responses are automatically parsed into Kotlin data classes:
NasaResponse.kt
package com.ccandeladev.nasaexplorer.data.apiimport com.ccandeladev.nasaexplorer.domain.NasaModeldata class NasaResponse( val copyright: String?, val date: String, val explanation: String, val hdurl: String?, val media_type: String, val service_version: String, val title: String, val url: String) { // Convert API response to domain model fun toNasaModel(): NasaModel { return NasaModel( title = title, url = url, explanation = explanation ) }}
The repository encapsulates API calls and handles data transformation:
NasaRepository.kt
package com.ccandeladev.nasaexplorer.data.apiimport com.ccandeladev.nasaexplorer.BuildConfigimport com.ccandeladev.nasaexplorer.domain.NasaModelimport javax.inject.Injectclass NasaRepository @Inject constructor( private val nasaApiService: NasaApiService) { companion object { private const val API_KEY = BuildConfig.NASA_API_KEY } // Get image of the day, optionally for a specific date suspend fun getImageOfTheDay(date: String? = null): NasaModel { val response = nasaApiService.getImageOfTheDay(apiKey = API_KEY, date = date) return response.toNasaModel() // Convert to domain model } // Get images in a date range suspend fun getImagesInRange(startDate: String, endDate: String? = null): List<NasaModel> { val response = nasaApiService.getImagesInRange( apiKey = API_KEY, startDate = startDate, endDate = endDate ) return response.map { it.toNasaModel() } } // Get a specific number of random images suspend fun getRandomImages(count: Int): List<NasaModel> { val response = nasaApiService.getRandomImages(apiKey = API_KEY, count = count) return response.map { it.toNasaModel() } }}