EBAC Logotipo
Menú

8.4 Comunicación FrontEnd-BackEnd mediante APIs (AJAX)

Verás cómo el frontend puede pedir datos al backend a través de una API, cómo se recibe esa información y cómo se muestra al usuario, usando un flujo real de ida y vuelta de datos.

1. Compara formularios nativos y dinámicos

Los formularios HTML tradicionales envían los datos al servidor usando los atributos action y method, y provocan una recarga completa de la página. Con JavaScript y AJAX, podemos interceptar ese envío, capturar los datos y procesarlos de forma más flexible.


Formulario HTML tradicional (sin JS):

  1. Usa action="/ruta" y method="POST"
  2. Envía automáticamente los campos con atributo name
  3. Envía una solicitud al server recargando la página en cada petición
  4. El backend responde con HTML


Formulario con JS y AJAX:

  1. Captura eventos con addEventListener("submit")
  2. Extrae campos con .value o FormData
  3. Envía datos con fetch()
  4. El backend responde con JSON
  5. Envía una solicitud sin recarga completa

2. Conoce AJAX

AJAX (Asynchronous JavaScript And XML) es una técnica que permite enviar y recibir datos entre el navegador y el servidor sin recargar la página. Aunque el nombre menciona XML, hoy se usa mayormente con JSON, y se usa para:


  1. Enviar formularios de forma dinámica
  2. Cargar datos sin interrumpir al usuario
  3. Mostrar errores, respuestas o resultados en tiempo real


Su flujo es:

  1. El usuario interactúa con la página (clic, submit, etc.)
  2. JavaScript captura el evento y prepara los datos
  3. Se hace una petición HTTP (GET, POST, etc.)
  4. El servidor responde con JSON u otro formato


AJAX es la base técnica de muchas aplicaciones interactivas modernas como chats, buscadores y gestores de tareas.

3. Conecta frontend y backend con una API

Una API transmite datos entre la interfaz del usuario y la lógica del servidor.

  1. El frontend muestra la información y permite al usuario interactuar.
  2. El backend gestiona la lógica, valida los datos y accede a la base.
  3. La API es el punto de encuentro entre ambas capas.


Ejemplo de flujo en un gestor de tareas:

  1. El usuario crea, consulta o edita tareas desde la interfaz.
  2. El frontend envía una petición (por ejemplo, GET /api/tareas) usando fetch.
  3. El backend recibe la solicitud, consulta la base de datos y responde con los datos en formato JSON.
  4. El frontend muestra los resultados al usuario.


Este flujo de ida y vuelta es la base de la comunicación en apps modernas.

4. Crea tu primera respuesta JSON desde tu API backend

Cuando el backend recibe una solicitud desde el frontend mediante una API, debe responder en formato JSON con:

  1. Un código de estado HTTP adecuado (200 OK, 201 Created, 400 Bad Request, etc.)
  2. Un mensaje legible que describa el resultado
  3. Los datos solicitados o generados, organizados como objetos o listas JSON

Ejemplo en Flask:

# Añade la importación de jsonify
from flask import jsonify, ...

@app.route("/api/tareas")
def api_tareas():
tareas = Tarea.get_all()
return jsonify([dict(row) for row in tareas])

¿Qué sucede aquí?

  1. Se obtienen las tareas desde la base de datos
  2. Cada objeto Tarea se convierte en un diccionario
  3. Se retorna una lista JSON lista para ser usada en el frontend
Asegúrate de que los atributos del modelo sean serializables y evita incluir datos sensibles innecesarios.

5. Dispara acciones con eventos del usuario

El primer paso del flujo ocurre cuando el usuario interactúa con un formulario en la interfaz. En nuestro gestor de tareas, esto sucede al hacer clic en el botón para agregar una nueva tarea. Un evento de JavaScript captura esta acción:

document.querySelector("#form-tarea").addEventListener("submit", (e) => {
e.preventDefault();
const titulo = document.querySelector("#titulo").value;
const categoria = categoriaSelector.getValue(true); // Devuelve string
enviarTarea({ title: titulo, category: categoria });
});

Envío de datos al backend:

fetch("/api/tareas", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title: "Estudiar Flask",
category: "Estudio",
status: "pendiente"
})
});

6. Procesa datos en el backend con Flask

Cuando el backend recibe datos desde el frontend mediante fetch(), procesa igual que una forma nativa, con la diferencia en recepción de respuesta y respuesta en formato JSON.


Ejemplo

@app.route("/api/tareas", methods=["POST"])
def crear_tarea():
datos = request.get_json()
categoria = Categoria.get_or_create(datos["category"])
nueva = Tarea.create(datos["title"], "pendiente", categoria.id)
return jsonify(dict(nueva)), 201

¿Qué hace esta función?

  1. Extrae los datos JSON enviados por el cliente
  2. Busca o crea la categoría correspondiente
  3. Crea una nueva instancia de Tarea y la guarda en la base de datos
  4. Devuelve la tarea en formato JSON junto con el código de estado 201 Created

7. Actualiza un registro desde el frontend usando fetch

Además de crear tareas, una API permite modificar registros existentes. Para ello, el frontend puede enviar una solicitud PUT o PATCH usando fetch() con los nuevos datos que reemplazarán los existentes.


Ejemplo en JavaScript:

fetch("/api/tareas/3", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title: "Estudiar Flask avanzado",
status: "completada"
})
});

Ejemplo en Flask (backend):

@app.route("/api/tareas/<int:id>", methods=["PUT"])
def actualizar_tarea(id):
datos = request.get_json()
title = datos["title"]
status = datos["status"]
Tarea.update(id, title, status)
return jsonify({"mensaje": "Tarea actualizada"}), 200

8. Eliminar una tarea desde la interfaz

Una API también permite eliminar registros de forma remota. Desde el frontend, puedes hacer una solicitud DELETE mediante fetch() para borrar una tarea específica.


Ejemplo en JavaScript:

fetch("/api/tareas/3", {
method: "DELETE"
});

Ejemplo en Flask (backend):

@app.route("/api/tareas/<int:id>", methods=["DELETE"])
def eliminar_tarea(id):
Tarea.delete(id)
return jsonify({"mensaje": "Tarea eliminada"}), 200

¿Qué ocurre en este flujo?

  1. El usuario hace clic en un botón para eliminar una tarea.
  2. El frontend envía una solicitud DELETE a la API con el ID correspondiente.
  3. El backend borra el registro de la base de datos.
  4. La respuesta indica que la operación fue exitosa.
  5. El frontend puede quitar el elemento de la interfaz sin recargar.

9. Maneja errores y estados en la comunicación


Cuando algo falla en el intercambio entre frontend y backend, la API debe indicar qué ocurrió. El frontend también debe reaccionar apropiadamente.


En el backend (Flask), puedes usar códigos de estado:

return jsonify({"error": "Datos incompletos"}), 400

En el frontend (JavaScript), se puede capturar errores así:

fetch("/api/tareas")
.then(res => {
if (!res.ok) throw new Error("Error en la API");
return res.json();
})
.then(data => { console.log("Proceso completado") })
Un sistema robusto responde bien ante fallos esperados o inesperados, controlando errores y respondiend con códigos HTTP claros.

10. Conclusión

Conocer el flujo API-frontend-backend te permite crear apps funcionales y responsivas, conectando la interfaz del usuario con la lógica de servidor en una aplicación web.


Recursos útiles:

  1. MDN fetch API
  2. DevTools - pestaña Network
  3. Axios: alternativa más amigable para trabajar con APIs.