GraphQL vs REST en Kotlin: qué elegir para el backend en 2025

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿REST ha muerto, larga vida a GraphQL? (Spoiler: no)

\n

Si programas en Kotlin y desarrollas backend, seguramente has oído hablar de la guerra santa: GraphQL vs REST. En una esquina del ring está el viejo y querido REST, que todo junior conoce. En la otra, el moderno GraphQL, que promete «dame lo que sea, pero con una sola consulta».

\n

Soy desarrollador backend con experiencia en Kotlin, y en los últimos años he reescrito tres proyectos de REST a GraphQL y viceversa. Spoiler: cada herramienta es buena para su tarea. En este artículo no seremos fanáticos. En su lugar, analizaremos con ejemplos de código reales cuándo gana REST en Kotlin y cuándo GraphQL es tu salvador.

\n

Vamos a ver la comparación de GraphQL y REST en Kotlin sin rodeos ni marketing.

\n\n

1. Brevemente sobre lo principal: qué es qué

\n

Antes de meternos en el código, acordemos los términos. REST API es un estilo arquitectónico donde cada recurso (usuario, pedido, producto) tiene su propia URL y métodos HTTP (GET, POST, PUT, DELETE). Los desarrolladores de Kotlin suelen usar Spring Boot o Ktor para crear servicios REST.

\n

GraphQL es un lenguaje de consultas donde tienes un único endpoint (generalmente /graphql), y el cliente decide qué campos necesita. En Kotlin son populares las bibliotecas KGraphQL (ligera) y Spring for GraphQL (para fanáticos de Spring).

\n

La diferencia clave: REST es «el servidor dicta qué devolver». GraphQL es «el cliente pide solo lo que necesita».

\n\n

2. Ejemplo de API REST en Kotlin (Ktor)

\n

Empecemos con lo clásico. Supongamos que tenemos una tienda en línea. Necesitamos obtener datos de un usuario y sus últimos pedidos.

\n

Así se ve un controlador REST típico en Ktor (framework ligero para Kotlin):

\n\n
// REST endpoint: GET /api/users/{id}\nfun Application.userModule() {\n    routing {\n        get("/api/users/{id}") {\n            val userId = call.parameters["id"]?.toIntOrNull() ?: return@get call.respondText("Bad Request", status = HttpStatusCode.BadRequest)\n            val user = userService.getUserById(userId) ?: return@get call.respondText("Not Found", status = HttpStatusCode.NotFound)\n            call.respond(user)\n        }\n    }\n}\n\n// Data class para la respuesta\n@Serializable\ndata class UserResponse(\n    val id: Int,\n    val name: String,\n    val email: String,\n    val lastOrders: List<Order>\n)
\n\n

Problema: si el cliente (aplicación móvil) solo necesita el email del usuario, el servidor igualmente devolverá el objeto completo UserResponse con los pedidos. Esto es over-fetching — transferencia excesiva de datos. En redes móviles lentas, esto duele.

\n

La solución número uno es crear varios endpoints pequeños: GET /api/users/{id}/email. Pero entonces aumenta la cantidad de solicitudes (under-fetching).

\n\n

3. Ejemplo de GraphQL en Kotlin (Spring for GraphQL)

\n

Ahora el mismo escenario, pero con GraphQL. Aquí está el esquema (schema.graphqls):

\n\n
type Query {\n    user(id: ID!): User\n}\n\ntype User {\n    id: ID!\n    name: String\n    email: String\n    lastOrders: [Order]\n}\n\ntype Order {\n    id: ID!\n    total: Float\n    date: String\n}
\n\n

Y este es el código Kotlin usando Spring for GraphQL (enfoque de anotaciones):

\n\n
@Controller\nclass UserController(private val userService: UserService) {\n\n    @QueryMapping\n    fun user(@Argument id: Int): User {\n        return userService.getUserById(id) ?: throw UserNotFoundException("User not found")\n    }\n}\n\n// Data class sin campos adicionales\ndata class User(val id: Int, val name: String, val email: String, val lastOrders: List<Order>)
\n\n

Ahora el cliente puede solicitar solo lo que necesita:

\n\n
query {\n    user(id: 42) {\n        email\n    }\n}

Blogs

Book Recommendations