Capítulo 4.2: Envio de Requisições GET
Tempo de estudo: 45 minutos
1. GET: Requisição de Telemetria da Frota Espacial
Uma requisição GET é o comando principal para obter dados. Em nosso Centro de Controle de Missão (CCM), isso é equivalente à pergunta: "Centro de Controle da Frota, relate a situação!"
Usaremos fetch
para enviar dois tipos de requisições GET ao nosso servidor FastAPI:
- Obtenção de toda a coleção: "Mostre-me toda a minha frota".
- Obtenção de um único recurso: "Forneça informações detalhadas sobre a nave com ID 2".
💡 Analogia espacial:
GET /spaceships
— é uma requisição de broadcast para toda a frota solicitando seus indicativos de chamada.
GET /spaceships/3
— é uma requisição direcionada a uma nave específica (ISS) solicitando a transmissão de dados completos de seus sistemas.
2. Problema CORS: "Interferência Interplanetária"
Antes de enviarmos a requisição, precisamos resolver um problema importante. Por padrão, por razões de segurança, os navegadores impedem que uma página web (nosso CCM), carregada de um "domínio" (file:///...
ou http://localhost:5500
), faça requisições a uma API em outro "domínio" (http://127.0.0.1:8000
).
Essa política é chamada de CORS (Compartilhamento de Recursos de Origem Cruzada).
Para permitir que nosso frontend se comunique com o backend, é preciso configurar o servidor FastAPI para que ele diga ao navegador: "Está tudo bem, confio nas requisições deste endereço".
Passo 1: Instalar python-multipart
Isso é necessário para o funcionamento correto do middleware.
Passo 2: Configurar CORS em main.py
Abra seu arquivo main.py
do projeto FastAPI e adicione o seguinte código:
# main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware # <-- Importamos o middleware
# ... seu restante do código (modelos, db_spaceships) ...
app = FastAPI(
title="Fleet Management API",
# ...
)
# --- CONFIGURAÇÃO CORS ---
# Indicamos quais "domínios" (origens) podem enviar requisições
origins = [
"http://localhost",
"http://localhost:8080",
"http://127.0.0.1:5500", # Endereço para Live Server no VS Code
"null" # Para requisições de arquivos locais file:///
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins, # Permite as origens especificadas
allow_credentials=True,
allow_methods=["*"], # Permite todos os métodos (GET, POST, etc.)
allow_headers=["*"], # Permite todos os cabeçalhos
)
# --- SEUS ENDPOINTS ABAIXO ---
@app.get("/")
# ...
uvicorn
para que as alterações entrem em vigor!
3. Obtendo a lista de todas as naves
Criaremos uma interface para exibir nossa frota.
Passo 1: Atualizar index.html
<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8">
<title>CCM - Gerenciamento de Frota</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>Painel de Controle da Frota Espacial</h1>
<button id="load-fleet-btn">Requisitar dados da frota</button>
<h2>Lista de aparelhos:</h2>
<ul id="fleet-list" class="ship-list">
<li>Aguardando comando...</li>
</ul>
<script src="app.js"></script> <!-- Conectando script externo -->
</body>
</html>
Passo 2: Criar app.js
Ao lado de index.html
, crie o arquivo app.js
. Nele, extrairemos toda a lógica.
// app.js
const API_BASE_URL = 'http://127.0.0.1:8000'; // URL do nosso servidor FastAPI
const loadFleetBtn = document.getElementById('load-fleet-btn');
const fleetList = document.getElementById('fleet-list');
// Função para carregar e exibir a frota
async function fetchAndDisplayFleet() {
try {
fleetList.innerHTML = '<li>Carregando telemetria...</li>';
// Enviando requisição GET para /spaceships
const response = await fetch(`${API_BASE_URL}/spaceships`);
if (!response.ok) {
throw new Error(`Erro de rede: ${response.status}`);
}
const ships = await response.json(); // Obtemos o array de naves
// Limpamos a lista e exibimos os dados
fleetList.innerHTML = '';
if (ships.length === 0) {
fleetList.innerHTML = '<li>Nenhum aparelho encontrado no 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>
Ano de lançamento: ${ship.launch_year}<br>
Status: ${ship.status}
`;
fleetList.appendChild(listItem);
});
} catch (error) {
console.error('Não foi possível carregar os dados da frota:', error);
fleetList.innerHTML = `<li>Erro: ${error.message}</li>`;
}
}
// Adiciona o manipulador de evento ao botão
loadFleetBtn.addEventListener('click', fetchAndDisplayFleet);
- async/await: Usamos uma nova e mais conveniente sintaxe para trabalhar com Promises. Abordaremos isso em detalhes no Capítulo 4.5. Por enquanto, saiba apenas que
await
"espera" a execução de uma Promise sem bloquear a página. try...catch
: Uma excelente maneira de lidar com erros em funçõesasync
.
Passo 3: Testar
Abra index.html
no navegador (preferencialmente via extensão Live Server no VS Code, que o executará em http://127.0.0.1:5500
). Clique no botão "Requisitar dados da frota". A lista das suas naves do FastAPI deverá aparecer na página!
4. Obtendo dados de uma única nave
Agora adicionaremos um formulário para requisitar informações por um ID específico.
Passo 1: Adicionar formulário em index.html
<!-- index.html, após a lista -->
<hr>
<h2>Requisição por ID</h2>
<form id="ship-form">
<input type="number" id="ship-id-input" placeholder="Digite o ID do aparelho" required>
<button type="submit">Encontrar aparelho</button>
</form>
<div id="ship-details" class="ship-list"></div>
Passo 2: Adicionar lógica em app.js
// app.js, no final do arquivo
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(); // Impede o recarregamento da página
const shipId = shipIdInput.value;
if (!shipId) {
alert('Por favor, insira o ID.');
return;
}
try {
shipDetails.innerHTML = '<li>Buscando aparelho...</li>';
// Enviando requisição GET para /spaceships/{id}
const response = await fetch(`${API_BASE_URL}/spaceships/${shipId}`);
if (response.status === 404) {
throw new Error('Aparelho com este ID não encontrado no registro.');
}
if (!response.ok) {
throw new Error(`Erro de rede: ${response.status}`);
}
const ship = await response.json();
shipDetails.innerHTML = `
<li>
<strong>${ship.name} (ID: ${ship.id})</strong><br>
Tipo: ${ship.type}<br>
Ano de lançamento: ${ship.launch_year}<br>
Status: ${ship.status}
</li>
`;
} catch (error) {
console.error(`Erro ao buscar aparelho ${shipId}:`, error);
shipDetails.innerHTML = `<li>Erro: ${error.message}</li>`;
}
}
shipForm.addEventListener('submit', fetchShipById);
- Adicionamos um tratamento separado para o status
404
para fornecer ao usuário uma mensagem de erro mais clara.
Passo 3: Testar Atualize a página, insira o ID de uma nave existente (por exemplo, 1) e clique em "Encontrar aparelho". Você deverá ver seus dados. Tente inserir um ID inexistente (por exemplo, 99) — você verá uma mensagem de erro.
Quiz para fixação
🚀 Resumo do Capítulo:
Você configurou com sucesso o canal de comunicação entre a "Terra" e o "espaço" e aprendeu a solicitar telemetria!
- 🛡️ Você resolveu o problema de "interferência interplanetária" configurando o CORS em seu servidor FastAPI.
- 🛰️ Implementou a função para obter e exibir a lista completa de espaçonaves.
- 🔭 Criou uma interface para solicitar dados sobre uma nave específica pelo seu ID.
O MCC está recebendo dados! No próximo capítulo, passaremos para ações ativas: enviaremos comandos para criar, atualizar e excluir nossas naves espaciais.
📌 Verificação:
- Certifique-se de que seu servidor FastAPI esteja rodando com o
CORSMiddleware
configurado.- Verifique se, ao clicar no botão "Solicitar dados", uma lista de naves aparece na página.
- Certifique-se de que o formulário de busca por ID encontra corretamente as naves existentes e reporta um erro para as não existentes.
⚠️ Se houver erros:
- Erro de CORS no console do navegador: Ou você não reiniciou o
uvicorn
após adicionar oCORSMiddleware
, ou o endereço do seu frontend (por exemplo,http://127.0.0.1:5500
) não foi adicionado à lista deorigins
.- Failed to fetch: Verifique se seu servidor FastAPI está rodando e acessível no endereço especificado em
API_BASE_URL
.