Introducción: evolución de las API en Java
\n\nEl mundo del desarrollo Java no se detiene. Hace solo 10 años, la elección era obvia: REST y JSON. Hoy en día, al diseñar una arquitectura de microservicios o una aplicación móvil, el desarrollador se enfrenta a todo un zoológico de protocolos. REST, GraphQL, gRPC — cada uno promete el paraíso, pero en realidad detrás de cada tecnología hay compromisos.
\n\nEn este artículo no vamos a repetir la documentación. Tomaremos un problema real: necesitamos crear una API para una plataforma educativa (como nuestro PythonLib, pero en Java). Tenemos cursos, estudiantes y progreso de aprendizaje. E intentaremos implementar el mismo endpoint de tres maneras diferentes.
\n\nVamos a descubrir qué protocolo hará tu código más rápido y tu vida más fácil.
\n\nAPI REST en Java: un clásico que nunca muere
\n\nREST (Representational State Transfer) es un estilo arquitectónico, no un protocolo. En Java, el estándar de facto para REST es Spring Boot con sus anotaciones. Simplicidad, claridad, una comunidad enorme — eso es lo que amamos de REST.
\n\nEjemplo: obtener lista de cursos
\n\nSupongamos que necesitamos devolver al cliente una lista de todos los cursos con información básica:
\n\n@RestController\n@RequestMapping("/api/courses")\npublic class CourseController {\n\n @GetMapping\n public ResponseEntity<List<CourseDTO>> getAllCourses() {\n List<Course> courses = courseService.findAll();\n List<CourseDTO> dtos = courses.stream()\n .map(c -> new CourseDTO(c.getId(), c.getTitle(), c.getAuthor()))\n .toList();\n return ResponseEntity.ok(dtos);\n }\n}\n\nEl cliente recibe JSON:
\n\n[\n {"id": 1, "title": "Java para principiantes", "author": "Iván Petrov"},\n {"id": 2, "title": "Spring Boot Masterclass", "author": "Ana Smirnova"}\n]\n\nVentajas de REST en Java:
\n- \n
- Barrera de entrada mínima: cualquier desarrollador Java conoce Spring. \n
- Almacenamiento en caché mediante cabeceras HTTP (ETag, Cache-Control). \n
- Amplio soporte de herramientas (Postman, Swagger, OpenAPI). \n
Desventajas:
\n- \n
- Problema de over-fetching (datos innecesarios) y under-fetching (datos insuficientes, necesidad de múltiples solicitudes). \n
- Tipado débil: todo depende del contrato, que es fácil de romper. \n
REST es ideal para API públicas, cuando los clientes son terceros y necesitas la máxima compatibilidad. Pero si tu cliente es una aplicación móvil que quiere recibir exactamente lo que necesita, REST empieza a ser molesto.
\n\nGraphQL en Java: dame solo lo que pido
\n\nGraphQL es un lenguaje de consultas creado por Facebook. En Java, se implementa más a menudo mediante la biblioteca graphql-java o la integración con Spring — GraphQL Kickstart.
\n\nEl cliente decide qué campos necesita. Sin over-fetching. Una sola consulta y obtienes los cursos junto con el progreso del estudiante.
\n\nEjemplo: esquema GraphQL y resolver
\n\nDefinimos el esquema:
\n\ntype Course {\n id: ID!\n title: String!\n author: String!\n progress(studentId: ID!): Int\n}\n\ntype Query {\n courses: [Course!]!\n}\n\nEscribimos el resolver en Java:
\n\n@Component\npublic class CourseResolver implements GraphQLQueryResolver {\n\n @Autowired\n private CourseService courseService;\n\n public List<Course> courses() {\n return courseService.findAll();\n }\n}\n\n@Component\npublic class CourseFieldResolver implements GraphQLResolver<Course> {\n\n @Autowired\n private ProgressService progressService;\n\n public Integer progress(Course course, Long studentId) {\n return progressService.getProgress(course.getId(), studentId);\n }\n}\n\nConsulta del cliente:
\n\nquery {\n courses {\n title\n