Angular · HttpClient · API REST · Integración frontend

Comunicación entre Angular y una API REST con HttpClient

Este artículo reúne varios patrones habituales cuando una aplicación Angular consume una API: petición GET, login por POST, filtrado de respuestas JSON, descarga de ficheros y tratamiento de estados de carga.

La idea es mantener la interfaz alineada con el resto del blog y, al mismo tiempo, dejar ejemplos reutilizables para futuros proyectos donde Angular actúe como cliente ligero sobre un backend independiente.

Qué se trabaja en este ejemplo

El backend expone varios recursos HTTP y Angular se encarga de consumirlos desde un servicio, procesar respuestas y reflejar correctamente carga, error y resultado en la vista.

La base de la API utilizada en el artículo es: https://servernuevo.1938.com.es/api/v1/

Casos cubiertos

  • Peticiones GET para recuperar información inicial.
  • Peticiones POST para autenticación y envío de datos.
  • Filtrado de respuestas usando `map`.
  • Descarga de blobs y gestión de ficheros PDF.
  • Separación entre componente visual y servicio de acceso HTTP.

1. Petición GET básica

El punto de partida es una llamada sencilla para recuperar un saludo desde la API. La lógica se encapsula en un servicio y el componente solo coordina estados y presentación.

Servicio Angular

Este primer fragmento define la llamada GET dentro del servicio. Su responsabilidad es muy concreta: construir la petición, ejecutarla con `HttpClient` y propagar cualquier error para que el componente pueda reaccionar.

La idea importante aquí es separar la comunicación HTTP del resto de la aplicación. Si mañana cambia la URL, la cabecera o la forma de tratar errores, el ajuste se hace en el servicio y no en cada componente visual.

Fichero del ejemplo: `consultarapi.service.ts`

Componente consumidor

Aquí el componente invoca el servicio, activa el estado de carga, limpia resultados anteriores y decide qué hacer cuando la API responde correctamente o devuelve un error.

Este reparto de responsabilidades es el patrón que más vas a repetir en Angular: el servicio obtiene datos, el componente decide cómo usarlos y la plantilla solo representa el estado resultante.

Fichero del ejemplo: `saludar-servidor.component.ts`

Vista HTML

La plantilla conecta la interacción del usuario con el método del componente y muestra de forma condicional el resultado o el spinner. Es la parte visible del flujo que hemos separado en los dos fragmentos anteriores.

Conviene fijarse en que la vista no contiene lógica de negocio. Solo enlaza eventos, muestra estados y enseña la respuesta al usuario, que es justo lo que queremos en una interfaz mantenible.

Fichero del ejemplo: `saludar-servidor.component.html`

Demo de la llamada GET

Este botón ejecuta el servicio y muestra la respuesta recibida por pantalla. El ejemplo sirve para revisar el flujo completo de carga, error y renderizado del JSON.

2. Login por POST

Otro patrón clásico consiste en autenticar al usuario enviando credenciales y recuperando un token. En este caso la API devuelve un JSON con la información de acceso que después puede reutilizarse para peticiones protegidas.

Este bloque implementa la petición POST de autenticación. Construye el payload con usuario y contraseña, lo envía al endpoint correspondiente y tipa la respuesta para trabajar después con el token.

A diferencia del GET anterior, aquí el cliente ya no solo consulta información: envía datos al servidor y espera una respuesta que condiciona el acceso al resto de recursos protegidos.

Fichero del ejemplo: `consultarapi.service.ts`

Modelo de usuario

Este modelo define la estructura mínima que Angular necesita para trabajar con las credenciales y el token devuelto por la API.

Tener este modelo separado ayuda a mantener el contrato con la API claro y evita tratar la respuesta como un objeto genérico sin estructura.

En proyectos pequeños a veces se omite este paso, pero definir el modelo desde el principio hace que el código sea más fácil de leer y reduce errores cuando la aplicación empieza a crecer.

Fichero del ejemplo: `user.ts`

Guardar token y renderizar estado

Una vez autenticado el usuario, el componente almacena el token y decide qué mostrar en pantalla.

Este código representa el paso intermedio entre autenticarse y usar la API protegida: comprobar si la respuesta es válida, guardar el token y actualizar el estado visual del componente.

Aunque aquí el ejemplo es sencillo, conceptualmente este es el punto donde el frontend pasa de ser un cliente anónimo a ser un cliente autenticado capaz de acceder a más funcionalidades del backend.

Fichero del ejemplo: `login.component.ts`

3. Filtrado de la respuesta JSON

A veces la API devuelve una estructura amplia y el componente solo necesita una parte. En ese escenario `map` permite exponer directamente la porción útil de la respuesta.

Este JSON simula una respuesta más compleja de la API. No siempre interesa renderizar el objeto completo: muchas veces solo una parte contiene la información relevante para la interfaz.

Este escenario es muy habitual cuando trabajas con APIs reales, porque la respuesta suele incluir metadatos, paginación, enlaces o estructuras internas que no necesitas mostrar directamente en pantalla.

El siguiente servicio transforma la respuesta y devuelve únicamente el bloque `datos`.

Aquí se usa `map` para extraer esa parte útil. Esto simplifica el componente, porque recibe ya el resultado adaptado al caso de uso en lugar de tener que navegar manualmente por toda la estructura JSON.

Cuando este tipo de transformación se resuelve en el servicio, el componente queda mucho más limpio y el patrón se vuelve reutilizable si otra parte de la aplicación necesita la misma información procesada.

Fichero del ejemplo: `consultarapi.service.ts`

Vista preparada para mostrar el JSON

La plantilla de este ejemplo mantiene la misma idea que en la petición GET: un botón para disparar la acción y una zona visual que enseña el contenido recibido o el estado de carga.

Esto también refuerza una idea importante del tutorial: aunque cambie el tipo de dato o la forma de obtenerlo, la estructura visual del componente puede mantenerse estable y predecible.

Fichero del ejemplo: `obtener-json.component.html`

Lógica del componente

En este fragmento el componente consume la respuesta ya transformada por el servicio y la deja lista para mostrarse por pantalla sin necesidad de procesado extra.

Eso hace que el componente se comporte casi igual que en el ejemplo GET, con la diferencia de que ahora el dato llega más depurado y adaptado al problema concreto.

Fichero del ejemplo: `obtener-json.component.ts`

4. Envío y descarga de ficheros

Las APIs no solo intercambian JSON. En muchos proyectos también hay que subir documentos, procesarlos en el servidor y devolver un blob descargable al usuario.

Formulario

El usuario selecciona un fichero y Angular lo inserta en un `FormData`.

Transporte

La petición POST envía el binario y espera otra respuesta en formato blob.

Descarga

El frontend genera un enlace temporal para descargar el PDF devuelto.

UX

El componente refleja el estado para evitar clics repetidos y errores silenciosos.

Formulario de subida

Este HTML representa la parte de entrada: el usuario selecciona un archivo, el formulario valida que exista y se prepara para enviarlo al backend.

Aquí el objetivo no es todavía subir nada, sino capturar correctamente el fichero y controlar que el usuario no envíe el formulario vacío o en un estado inválido.

Fichero del ejemplo: `cargarfichero.component.html`

Captura del fichero

El siguiente método toma el archivo seleccionado en el input y lo guarda dentro del formulario reactivo, que será el origen del `FormData` que viajara a la API.

Este paso suele generar dudas al principio porque el input de tipo file no se trata como un campo de texto normal. Por eso conviene aislar esa lógica en un método específico.

Fichero del ejemplo: `cargarfichero.component.ts`

POST del fichero

Aquí se construye la petición que envía el documento al servidor. La particularidad es que no esperamos un JSON, sino otra respuesta binaria preparada para ser descargada después por el usuario.

Esa diferencia es clave: cuando trabajas con ficheros, Angular necesita que le indiques expresamente el tipo de respuesta esperado para no intentar interpretar el contenido como si fuera JSON.

Fichero del ejemplo: `consultarapi.service.ts`

Recepción del blob

Este bloque muestra cómo tratar la respuesta del servidor cuando llega como blob: se genera una URL temporal y se lanza la descarga del archivo desde el propio navegador.

Es, en el fondo, el puente entre la respuesta técnica del backend y la experiencia del usuario final, que espera simplemente recibir un documento descargable.

Fichero del ejemplo: `cargarfichero.component.ts`

Ejemplo Python del endpoint

Para entender mejor qué recibe Angular, aquí se ve el lado del servidor: un recurso Python que localiza un fichero en disco y lo devuelve como respuesta HTTP descargable.

Ver ambos lados, backend y frontend, ayuda a comprender mejor por qué el navegador recibe un blob y qué comportamiento se espera exactamente cuando el endpoint responde correctamente.

Fichero del ejemplo: `api.py` o recurso Python equivalente

Servicio Angular para descargar

Desde Angular, el servicio debe indicar correctamente cabeceras y `responseType` para que la respuesta no se interprete como JSON y pueda tratarse como un archivo binario.

Este detalle suele ser el que marca la diferencia entre una descarga que funciona y una integración que falla con errores de parseo o con un archivo corrupto.

Fichero del ejemplo: `consultarapi.service.ts`

Demo de descarga

El componente reutilizable inferior encapsula la lógica de descarga del PDF y deja la página principal centrada en la explicación del patrón.

Descarga de PDF desde la API

Ejemplo práctico de respuesta `blob` y descarga del fichero generado por el backend.

Vista del botón de descarga

Esta plantilla es la versión reducida del componente de descarga. Su función es ofrecer una acción clara al usuario y reflejar visualmente si hay carga o si la respuesta ha llegado correctamente.

El interés de este ejemplo es que demuestra cómo encapsular un comportamiento completo dentro de un componente pequeño y reutilizable.

Fichero del ejemplo: `descargar-pdf.component.html`

Lógica del componente de descarga

Finalmente, este bloque une todas las piezas: llama al servicio, controla el estado del spinner y dispara la descarga efectiva del PDF cuando el backend responde.

Si comparas este flujo con el de los apartados anteriores, verás que la filosofía general no cambia: servicio para la comunicación, componente para el estado y plantilla para la representación.

Fichero del ejemplo: `descargar-pdf.component.ts`

5. Idea principal

La clave de esta integración no es solo llamar a la API, sino separar correctamente servicio HTTP, estado del componente y presentación visual. Esa separación hace que el código sea más fácil de mantener, más reutilizable y más consistente con el resto del proyecto.