Creación de APIs RESTful con Feign y Spring Boot

Clase 34 de 39Curso de Programación Funcional con Java SE

Contenido del curso

Functional Programming en Java

Optional y Streams: Datos mas interesantes

Todo junto: Proyecto Job-search

Resumen

Construir un cliente HTTP que consuma una API REST puede parecer complejo, pero con Feign el proceso se reduce a definir una interfaz y dejar que la librería haga el trabajo pesado. A continuación se explica paso a paso cómo estructurar un proyecto Java para consumir la API de GitHub Jobs, desde la creación de la interfaz hasta el aislamiento de dependencias mediante funciones puras.

¿Cómo se define la interfaz de consumo con Feign?

El punto de partida es crear un paquete llamado api donde vivirá toda la lógica de comunicación con el servicio externo [0:10]. Dentro de ese paquete se crea una interfaz — no una clase — llamada ApiJobs. Feign trabaja precisamente con interfaces: nosotros describimos qué queremos consumir y la librería genera la implementación.

La interfaz contiene un método que devuelve una lista de objetos JobPosition. Para que Feign sepa cómo realizar la petición, se utilizan tres anotaciones clave [0:46]:

  • @Headers: indica las cabeceras HTTP; en este caso Accept: application/json, porque la API devuelve JSON.
  • @RequestLine: describe el verbo y la ruta, por ejemplo GET /positions.json, tal como aparece en la documentación de GitHub.
  • @QueryMap: recibe un Map<String, Object> con los parámetros que se enviarán como query string en la URL.

Con estas tres anotaciones queda completamente definido el comportamiento de la petición web sin escribir código de conexión manual [1:15].

¿Qué es un POJO y cómo se mapea la respuesta JSON?

Para representar cada oferta de trabajo que devuelve la API se crea la clase JobPosition [1:30]. Este tipo de objeto se conoce como POJO (Plain Old Java Object): una clase sencilla con propiedades, getters y setters, sin lógica de negocio.

Los campos de la clase corresponden a los datos que entrega la API de GitHub:

  • id, type, url, title, location, description — se nombran igual que en el JSON, por lo que no requieren configuración adicional.
  • createdAt, companyUrl, companyLogo — tienen nombres distintos en el JSON (created_at, company_url, company_logo), así que se anota cada campo con @SerializedName para indicar el nombre real dentro del objeto JSON [1:55].

Por ejemplo, aunque la fecha de creación es técnicamente una fecha, se almacena como String porque ese es el tipo que la API devuelve directamente. Esto simplifica el mapeo y evita conversiones innecesarias [1:48].

¿Cómo se generan los getters y setters rápidamente?

Desde el IDE basta con usar la opción Generate → Getters and Setters, seleccionar todos los campos y confirmar [2:40]. Así la clase queda lista para que el decoder de JSON pueda poblar cada propiedad automáticamente al recibir la respuesta.

¿Por qué aislar la construcción del cliente en una función estática?

Una vez definida la interfaz y el POJO, se necesita una forma de instanciar el cliente Feign. Para ello se crea una interfaz auxiliar llamada ApiFunctions con un método estático y genérico: buildApi [3:05].

java static <T> T buildApi(Class<T> clazz, String url) { return Feign.builder() .decoder(new GsonDecoder()) .target(clazz, url); }

Este método recibe la clase de la API y la URL base, construye el cliente y decodifica las respuestas con JSON [3:20]. Aislarlo ofrece ventajas importantes:

  • Encapsulamiento: el resto del código desconoce que internamente se usa Feign. Si mañana se reemplaza por otra librería, solo cambia esta función.
  • Función pura: dados los mismos parámetros, siempre devuelve el mismo tipo de objeto, lo que facilita las pruebas y el mantenimiento [3:40].
  • Bajo acoplamiento: ningún otro módulo importa Feign directamente, lo que reduce el impacto de cambios futuros en las dependencias.

Este patrón de diseño permite intercambiar librerías HTTP de forma transparente, algo especialmente valioso cuando un proyecto crece y las necesidades cambian.

¿Has implementado clientes REST con Feign o prefieres otra librería? Comparte tu experiencia y las ventajas que has encontrado.