Capítulo 4.2: Envío de solicitudes GET
Tiempo de estudio: 45 minutos
1. GET: Solicitud de telemetría de la flota espacial
Una solicitud GET es el comando principal para obtener datos. En nuestro MCC (Centro de Control de Misiones), esto es equivalente a la solicitud: "¡Centro de Gestión de Flotas, informen la situación!"
Usaremos fetch
para enviar dos tipos de solicitudes GET a nuestro servidor FastAPI:
- Obtener la colección completa: "Muéstrame toda mi flota".
- Obtener un solo recurso: "Dame información detallada sobre la nave con ID 2".
💡 Analogía espacial:
GET /spaceships
es una solicitud de difusión a toda la flota pidiendo que informen sus distintivos de llamada.
GET /spaceships/3
es una solicitud dirigida a una nave específica (ISS) pidiendo que transmita datos completos sobre sus sistemas.
2. Problema de CORS: "Interferencia interplanetaria"
Antes de enviar la solicitud, debemos resolver un problema importante. Por defecto, por razones de seguridad, los navegadores impiden que una página web (nuestro MCC), cargada desde un "dominio" (file:///...
o http://localhost:5500
), realice solicitudes a una API en otro "dominio" (http://127.0.0.1:8000
).
Esta política se llama CORS (Cross-Origin Resource Sharing).
Para permitir que nuestro frontend se comunique con el backend, debemos configurar el servidor FastAPI para que le diga al navegador: "Está bien, confío en las solicitudes de esta dirección".
Paso 1: Instalar python-multipart
Esto es necesario para que el middleware funcione correctamente.
Paso 2: Configurar CORS en main.py
Abre tu archivo main.py
del proyecto FastAPI y añade el siguiente código:
# main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware # <-- Importamos el middleware
# ... tu código restante (modelos, db_spaceships) ...
app = FastAPI(
title="Fleet Management API",
# ...
)
# --- CONFIGURACIÓN CORS ---
# Especificamos qué "dominios" (origins) pueden enviar solicitudes
origins = [
"http://localhost",
"http://localhost:8080",
"http://127.0.0.1:5500", # Dirección para Live Server en VS Code
"null" # Para solicitudes desde archivos locales file:///
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins, # Permitimos los origins especificados
allow_credentials=True,
allow_methods=["*"], # Permitimos todos los métodos (GET, POST, etc.)
allow_headers=["*"], # Permitimos todos los encabezados
)
# --- TUS ENDPOINTS ABAJO ---
@app.get("/")
# ...
uvicorn
para que los cambios surtan efecto!
3. Obtener la lista de todas las naves
Crearemos una interfaz para mostrar nuestra flota.
Paso 1: Actualizar index.html
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>MCC - Gestión de Flotas</title>
<style>
body { font-family: sans-serif; }
.ship-list { list-style: none; padding: 0; }
.ship-list li { border: 1px solid #ccc; margin-bottom: 10px; padding: 15px; border-radius: 5px; }
</style>
</head>
<body>
<h1>Panel de control de la flota espacial</h1>
<button id="load-fleet-btn">Solicitar datos de la flota</button>
<h2>Lista de naves:</h2>
<ul id="fleet-list" class="ship-list">
<li>Esperando comando...</li>
</ul>
<script src="app.js"></script> <!-- Conectando script externo -->
</body>
</html>
Paso 2: Crear app.js
Junto a index.html
, crea el archivo app.js
. En él, trasladaremos toda la lógica.
// app.js
const API_BASE_URL = 'http://127.0.0.1:8000'; // URL de nuestro servidor FastAPI
const loadFleetBtn = document.getElementById('load-fleet-btn');
const fleetList = document.getElementById('fleet-list');
// Función para cargar y mostrar la flota
async function fetchAndDisplayFleet() {
try {
fleetList.innerHTML = '<li>Cargando telemetría...</li>';
// Enviamos una solicitud GET a /spaceships
const response = await fetch(`${API_BASE_URL}/spaceships`);
if (!response.ok) {
throw new Error(`Error de red: ${response.status}`);
}
const ships = await response.json(); // Obtenemos un array de naves
// Limpiamos la lista y mostramos los datos
fleetList.innerHTML = '';
if (ships.length === 0) {
fleetList.innerHTML = '<li>No hay ninguna nave en el registro.</li>';
return;
}
ships.forEach(ship => {
const listItem = document.createElement('li');
listItem.innerHTML = `
<strong>${ship.name} (ID: ${ship.id})</strong><br>
Tipo: ${ship.type}<br>
Año de lanzamiento: ${ship.launch_year}<br>
Estado: ${ship.status}
`;
fleetList.appendChild(listItem);
});
} catch (error) {
console.error('No se pudieron cargar los datos de la flota:', error);
fleetList.innerHTML = `<li>Error: ${error.message}</li>`;
}
}
// Añadimos el manejador de eventos al botón
loadFleetBtn.addEventListener('click', fetchAndDisplayFleet);
- async/await: Hemos utilizado una sintaxis nueva y más conveniente para trabajar con promesas. La analizaremos en detalle en el Capítulo 4.5. Por ahora, simplemente sepan que
await
"espera" la ejecución de una promesa sin bloquear la página. try...catch
: Una excelente manera de manejar errores en funcionesasync
.
Paso 3: Probar
Abre index.html
en tu navegador (preferiblemente a través de la extensión Live Server en VS Code, que lo ejecutará en http://127.0.0.1:5500
). Haz clic en el botón "Solicitar datos de la flota". ¡La lista de tus naves de FastAPI debería aparecer en la página!
4. Obtener los datos de una sola nave
Ahora añadiremos un formulario para solicitar información por ID específico.
Paso 1: Añadir formulario en index.html
<!-- index.html, después de la lista -->
<hr>
<h2>Solicitud por ID</h2>
<form id="ship-form">
<input type="number" id="ship-id-input" placeholder="Introduce el ID de la nave" required>
<button type="submit">Buscar nave</button>
</form>
<div id="ship-details" class="ship-list"></div>
Paso 2: Añadir lógica en app.js
// app.js, al final del archivo
const shipForm = document.getElementById('ship-form');
const shipIdInput = document.getElementById('ship-id-input');
const shipDetails = document.getElementById('ship-details');
async function fetchShipById(event) {
event.preventDefault(); // Prevenimos la recarga de la página
const shipId = shipIdInput.value;
if (!shipId) {
alert('Por favor, introduce un ID.');
return;
}
try {
shipDetails.innerHTML = '<li>Buscando nave...</li>';
// Enviamos una solicitud GET a /spaceships/{id}
const response = await fetch(`${API_BASE_URL}/spaceships/${shipId}`);
if (response.status === 404) {
throw new Error('Nave con ese ID no encontrada en el registro.');
}
if (!response.ok) {
throw new Error(`Error de red: ${response.status}`);
}
const ship = await response.json();
shipDetails.innerHTML = `
<li>
<strong>${ship.name} (ID: ${ship.id})</strong><br>
Tipo: ${ship.type}<br>
Año de lanzamiento: ${ship.launch_year}<br>
Estado: ${ship.status}
</li>
`;
} catch (error) {
console.error(`Error al buscar la nave ${shipId}:`, error);
shipDetails.innerHTML = `<li>Error: ${error.message}</li>`;
}
}
shipForm.addEventListener('submit', fetchShipById);
- Hemos añadido un manejo separado para el estado
404
para proporcionar al usuario un mensaje de error más claro.
Paso 3: Probar Actualiza la página, introduce el ID de una nave existente (por ejemplo, 1) y haz clic en "Buscar nave". Deberías ver sus datos. Intenta introducir un ID inexistente (por ejemplo, 99) — verás un mensaje de error.
Cuestionario para consolidar
🚀 Resumen del capítulo:
¡Has configurado con éxito un canal de comunicación entre "Tierra" y "espacio" y has aprendido a solicitar telemetría!
- 🛡️ Has resuelto el problema de la "interferencia interplanetaria" configurando CORS en tu servidor FastAPI.
- 🛰️ Has implementado una función para obtener y mostrar la lista completa de naves espaciales.
- 🔭 Has creado una interfaz para solicitar datos sobre un aparato específico por su ID.
¡El Centro de Control de la Misión recibe datos! En el próximo capítulo, pasaremos a la acción: enviaremos comandos para crear, actualizar y eliminar nuestras naves espaciales.
📌 Verificación:
- Asegúrate de que tu servidor FastAPI esté en ejecución con
CORSMiddleware
configurado.- Verifica que al hacer clic en el botón "Solicitar datos" en la página aparezca la lista de naves.
- Asegúrate de que el formulario de búsqueda por ID encuentre correctamente las naves existentes e informe un error para las que no existen.
⚠️ Si hay errores:
- CORS error en la consola del navegador: O no has reiniciado
uvicorn
después de añadirCORSMiddleware
, o la dirección de tu frontend (por ejemplo,http://127.0.0.1:5500
) no está añadida a la lista deorigins
.- Failed to fetch: Verifica que tu servidor FastAPI esté en ejecución y accesible en la dirección indicada en
API_BASE_URL
.