Cómo conectar tu aplicación de Android a una API con Retrofit y Kotlin
Antonio Leiva

Retrofit es una biblioteca de Android desarrollada por Square que facilita la implementación de peticiones HTTP en nuestras aplicaciones.

Esta biblioteca es muy popular y utilizada por desarrolladores de todo el mundo debido a su simplicidad y facilidad de uso.

En este artículo, veremos cómo utilizar Retrofit para crear una conexión a una API de películas y realizar operaciones CRUD (crear, leer, actualizar y eliminar) utilizando Kotlin como lenguaje de programación.

Para empezar, necesitamos agregar la dependencia de Retrofit y del adapter de Gson en nuestro archivo build.gradle:

implementation 'com.squareup.retrofit2:retrofit:2.7.2'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

A continuación, creamos una interfaz que define los métodos que utilizaremos para realizar las operaciones CRUD en la API de películas. En este ejemplo, utilizaremos la API de The Movie Database (TMDb):

interface MovieAPI {
    // Método para crear una película
    @POST("movie")
    fun createMovie(@Body movie: Movie): Call<Movie>
    
    // Método para obtener todas las películas
    @GET("movie")
    fun getMovies(): Call<List<Movie>>
    
    // Método para obtener una película por su ID
    @GET("movie/{id}")
    fun getMovie(@Path("id") id: Int): Call<Movie>
    
    // Método para actualizar una película
    @PUT("movie/{id}")
    fun updateMovie(@Path("id") id: Int, @Body movie: Movie): Call<Movie>
    
    // Método para eliminar una película
    @DELETE("movie/{id}")
    fun deleteMovie(@Path("id") id: Int): Call<Void>
}

En cada uno de estos métodos, especificamos el tipo de petición HTTP que utilizaremos (POST, GET, PUT o DELETE) y la ruta de la API donde se realizará la petición.

Además, en los métodos que reciben o envían una película, utilizamos la anotación @Body para indicar que el cuerpo de la petición será el objeto de tipo Movie.

Ahora, creamos una clase que implemente esta interfaz y que utilice Retrofit para realizar las peticiones HTTP:

class MovieService {
    // Instancia de Retrofit
    private val retrofit = Retrofit.Builder()
        .baseUrl("https://api.themoviedb.org/3/")
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    // Método para crear una película
    fun createMovie(movie: Movie) {
        movieAPI.createMovie(movie).enqueue(object : Callback<Movie> {
            override fun onResponse(call: Call<Movie>, response: Response<Movie>) {
                // Procesar respuesta exitosa
            }

            override fun onFailure(call: Call<Movie>, t: Throwable) {
                // Procesar error en la petición
            }
        })
    }

    // Método para obtener todas las películas
    fun getMovies() {
        movieAPI.getMovies().enqueue(object : Callback<List<Movie>> {
            override fun onResponse(call: Call<List<Movie>>, response: Response<List<Movie>>) {
                // Procesar respuesta exitosa
            }

            override fun onFailure(call: Call<List<Movie>>, t: Throwable) {
                // Procesar error en la petición
            }
        })
    }

    // Método para obtener una película por su ID
    fun getMovie(id: Int) {
        movieAPI.getMovie(id).enqueue(object : Callback<Movie> {
            override fun onResponse(call: Call<Movie>, response: Response<Movie>) {
                // Procesar respuesta exitosa
            }

            override fun onFailure(call: Call<Movie>, t: Throwable) {
                // Procesar error en la petición
            }
        })
    }

    // Método para actualizar una película
    fun updateMovie(id: Int, movie: Movie) {
        movieAPI.updateMovie(id, movie).enqueue(object : Callback<Movie> {
            override fun onResponse(call: Call<Movie>, response: Response<Movie>) {
                // Procesar respuesta exitosa
            }

            override fun onFailure(call: Call<Movie>, t: Throwable) {
                // Procesar error en la petición
            }
        })
    }

    // Método para eliminar una película
    fun deleteMovie(id: Int) {
        movieAPI.deleteMovie(id).enqueue(object : Callback<Void> {
            override fun onResponse(call: Call<Void>, response: Response<Void>) {
                // Procesar respuesta exitosa
            }

            override fun onFailure(call: Call<Void>, t: Throwable) {
                // Procesar error en la petición
            }
        })
    }
}

En esta clase, utilizamos Retrofit para crear una instancia de la interfaz MovieAPI. Luego, en cada uno de los métodos, utilizamos esta instancia para realizar la petición correspondiente a la operación CRUD deseada. También utilizamos el método enqueue() para ejecutar la petición en un hilo en segundo plano y recibir la respuesta en un callback.

Por último, en nuestro código podemos utilizar esta clase de la siguiente manera para realizar las operaciones CRUD en la API de películas:

val movieService = MovieService()

// Crear una película
val movie = Movie(...)
movieService.createMovie(movie)

// Obtener todas las películas
movieService.getMovies()

// Obtener una película por su ID
val id = 1
movieService.getMovie(id)

// Actualizar una película
val updatedMovie = Movie(...)
movieService.updateMovie(id, updatedMovie)

// Eliminar una película
movieService.deleteMovie(id)

Retrofit tiene soporte para corrutinas

Si utilizamos el soporte oficial de la librería Retrofit para corrutinas, el código cambia de la siguiente manera.

La interfaz MovieAPI se modifica para crear funciones suspend:

interface MovieAPI {
    // Método para crear una película
    @POST("movie")
    suspend fun createMovie(@Body movie: Movie): Movie
    
    // Método para obtener todas las películas
    @GET("movie")
    suspend fun getMovies(): List<Movie>
    
    // Método para obtener una película por su ID
    @GET("movie/{id}")
    suspend fun getMovie(@Path("id") id: Int): Movie
    
    // Método para actualizar una película
    @PUT("movie/{id}")
    suspend fun updateMovie(@Path("id") id: Int, @Body movie: Movie): Movie
    
    // Método para eliminar una película
    @DELETE("movie/{id}")
    suspend fun deleteMovie(@Path("id") id: Int): Void
}

Y la clase MovieService también tendrá métodos suspend. Un ejemlo:

    // Método para obtener todas las películas
    suspend fun getMovies(): List<Movie> {
        return movieAPI.getMovies()
    }

En nuestro código, podemos utilizar esta clase de la siguiente manera:

// Obtener todas las películas
GlobalScope.launch(Dispatchers.Main) {
    val movies = movieService.getMovies()
    // Procesar lista de películas
}

En resumen, Retrofit nos permite implementar peticiones HTTP de manera sencilla y eficiente en nuestras aplicaciones de Android utilizando Kotlin.

Con esta biblioteca, podemos conectar nuestra aplicación a cualquier API y realizar operaciones CRUD de manera rápida y sencilla.

Quizá también te interese…

Cómo crear un backend en Kotlin usando Ktor

Cómo crear un backend en Kotlin usando Ktor

Ktor es un framework de servidor web ligero y rápido para Kotlin, desarrollado por JetBrains. Es ideal para crear aplicaciones web y servicios RESTful, y es muy fácil de usar y configurar. En este artículo, vamos a ver cómo crear un backend para una aplicación de...

Cómo simular una base de datos reactiva en Room con Fakes

Cómo simular una base de datos reactiva en Room con Fakes

En el desarrollo de aplicaciones móviles es muy común utilizar bases de datos para almacenar y gestionar la información que se utiliza en la aplicación. En el caso de Android, una de las opciones más populares es Room, una librería de persistencia de datos que...

Flows de Kotlin para implementar búsquedas en tiempo real

Flows de Kotlin para implementar búsquedas en tiempo real

En Android, los Flows de Kotlin son una manera de representar secuencias de datos asincrónicas que emiten valores de forma continua. Estos Flows pueden ser útiles en situaciones en las que deseamos escuchar eventos y procesar los resultados de forma asíncrona, como en...

2 Comentarios

  1. neoranga55

    Lo primero gracias por la serie de artículos sobre Kotlin, es muy útil y la estoy disfrutando mucho como buen acompañamiento al libro de Kotlin.

    El ejemplo de apply es interesante pero muy abstracto para mi, ¿podrías por favor explicar un poco más cómo funciona y a qué métodos reemplaza?

    Responder
    • Antonio Leiva

      apply lo que hace es recibir en su función de extensión el objeto que llama a la función. Creo que queda más claro con una vista. Podrías hacer:


      val textView: TextView = TextView(this).apply {
      text = "Hello"
      textColor = Color.BLACK
      }

      Si dentro del apply haces «this», te estás refiriendo al TextView. Esto te permite utilizar una estructura de builder para clases que no tienen un builder. El caso de este artículo es muy sencillo, pero te ahorras el tener que crear una variable antes, y llamar a interceptor.level = ... para luego asignárselo ahí. Lo puedes hacer de forma más compacta.

      Responder

Enviar un comentario

Los datos personales que proporciones a través de este formulario quedarán registrados en un fichero de DevExpert, S.L.U., con el fin de gestionar los comentarios que realizas en este blog. La legitimación se realiza a través del consentimiento de la parte interesada. Si no se acepta, no podrás comentar en este blog. Los datos que proporciona solo se utilizan para evitar el correo no deseado y no se usarán para nada más. Puede ejercer los derechos de acceso, rectificación, cancelación y oposición en contacto@devexperto.com.

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Acepto la política de privacidad *