Skip to content

Chapter 4.2: Sending GET Requests

Study time: 45 minutes


1. GET: Requesting Telemetry from the Space Fleet

A GET request is the primary command for retrieving data. In our Mission Control, this is equivalent to the request: "Fleet Command, report status!"

We will use fetch to send two types of GET requests to our FastAPI server:

  1. Get the entire collection: "Show me my entire fleet."
  2. Get a single resource: "Give me detailed information about the ship with ID 2."

💡 Space Analogy:

GET /spaceships is a broadcast request to the entire fleet asking for their call signs.

GET /spaceships/3 is a targeted request to a specific ship (like the ISS) asking for full data on its systems.


2. The CORS Problem: "Interplanetary Interference"

Before we send a request, we need to solve one important problem. By default, for security reasons, browsers prohibit a web page (our Mission Control) loaded from one "origin" (file:///... or http://localhost:5500) from making requests to an API on another "origin" (http://127.0.0.1:8000).

This policy is called CORS (Cross-Origin Resource Sharing).

To allow our frontend to communicate with the backend, we need to configure the FastAPI server to tell the browser: "It's okay, I trust requests from this address."

Step 1: Install python-multipart This is necessary for the middleware to work correctly.

pip install python-multipart

Step 2: Configure CORS in main.py Open your main.py file from the FastAPI project and add the following code:

# main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware  # <-- Import the middleware

# ... your other code (models, db_spaceships) ...

app = FastAPI(
    title="Fleet Management API",
    # ...
)

# --- CORS CONFIGURATION ---
# Specify which "origins" can send requests
origins = [
    "http://localhost",
    "http://localhost:8080",
    "http://127.0.0.1:5500",  # Address for Live Server in VS Code
    "null"  # For requests from local file:///
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,  # Allow the specified origins
    allow_credentials=True,
    allow_methods=["*"],  # Allow all methods (GET, POST, etc.)
    allow_headers=["*"],  # Allow all headers
)

# --- YOUR ENDPOINTS BELOW ---
@app.get("/")
# ...
Now our API server is ready to accept requests from the frontend. Restart uvicorn for the changes to take effect!


3. Getting the List of All Ships

Let's create an interface to display our fleet.

Step 1: Update index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Mission Control - Fleet Management</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>Space Fleet Control Panel</h1>

    <button id="load-fleet-btn">Request Fleet Data</button>

    <h2>List of Crafts:</h2>
    <ul id="fleet-list" class="ship-list">
        <li>Awaiting command...</li>
    </ul>

    <script src="app.js"></script> <!-- Include external script -->
</body>
</html>

Step 2: Create app.js Next to index.html, create a file app.js. We will move all the logic into it.

// app.js

const API_BASE_URL = 'http://127.0.0.1:8000'; // URL of our FastAPI server

const loadFleetBtn = document.getElementById('load-fleet-btn');
const fleetList = document.getElementById('fleet-list');

// Function to load and display the fleet
async function fetchAndDisplayFleet() {
    try {
        fleetList.innerHTML = '<li>Loading telemetry...</li>';

        // Send a GET request to /spaceships
        const response = await fetch(`${API_BASE_URL}/spaceships`);

        if (!response.ok) {
            throw new Error(`Network error: ${response.status}`);
        }

        const ships = await response.json(); // Get the array of ships

        // Clear the list and display the data
        fleetList.innerHTML = '';
        if (ships.length === 0) {
            fleetList.innerHTML = '<li>No crafts found in the registry.</li>';
            return;
        }

        ships.forEach(ship => {
            const listItem = document.createElement('li');
            listItem.innerHTML = `
                <strong>${ship.name} (ID: ${ship.id})</strong><br>
                Type: ${ship.type}<br>
                Launch Year: ${ship.launch_year}<br>
                Status: ${ship.status}
            `;
            fleetList.appendChild(listItem);
        });

    } catch (error) {
        console.error('Failed to load fleet data:', error);
        fleetList.innerHTML = `<li>Error: ${error.message}</li>`;
    }
}

// Add event listener to the button
loadFleetBtn.addEventListener('click', fetchAndDisplayFleet);

  • async/await: We used a new, more convenient syntax for working with promises. We will discuss it in detail in Chapter 4.5. For now, just know that await "waits" for the promise to complete without blocking the page.
  • try...catch: An excellent way to handle errors in async functions.

Step 3: Testing Open index.html in your browser (preferably with the Live Server extension in VS Code, which will run it at http://127.0.0.1:5500). Click the "Request Fleet Data" button. The list of your ships from FastAPI should appear on the page!


4. Getting Data for a Single Ship

Now let's add a form to request information by a specific ID.

Step 1: Add the form to index.html

<!-- index.html, after the list -->
<hr>
<h2>Request by ID</h2>
<form id="ship-form">
    <input type="number" id="ship-id-input" placeholder="Enter craft ID" required>
    <button type="submit">Find Craft</button>
</form>
<div id="ship-details" class="ship-list"></div>

Step 2: Add logic to app.js

// app.js, at the end of the file

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(); // Prevent the page from reloading
    const shipId = shipIdInput.value;

    if (!shipId) {
        alert('Please enter an ID.');
        return;
    }

    try {
        shipDetails.innerHTML = '<li>Searching for craft...</li>';

        // Send a GET request to /spaceships/{id}
        const response = await fetch(`${API_BASE_URL}/spaceships/${shipId}`);

        if (response.status === 404) {
             throw new Error('Craft with this ID not found in the registry.');
        }
        if (!response.ok) {
            throw new Error(`Network error: ${response.status}`);
        }

        const ship = await response.json();

        shipDetails.innerHTML = `
            <li>
                <strong>${ship.name} (ID: ${ship.id})</strong><br>
                Type: ${ship.type}<br>
                Launch Year: ${ship.launch_year}<br>
                Status: ${ship.status}
            </li>
        `;
    } catch (error) {
        console.error(`Error searching for craft ${shipId}:`, error);
        shipDetails.innerHTML = `<li>Error: ${error.message}</li>`;
    }
}

shipForm.addEventListener('submit', fetchShipById);

  • We added separate handling for the 404 status to give the user a more understandable error message.

Step 3: Testing Refresh the page, enter the ID of an existing ship (e.g., 1), and click "Find Craft". You should see its data. Try entering a non-existent ID (e.g., 99) — you will see an error message.


Quiz to Reinforce

1. The browser's CORS policy is for...

2. To allow a frontend on `localhost:5500` to access FastAPI, you need to...

3. To get data for a specific resource with ID=5, the request URL will look like:

4. The `await` keyword in JavaScript can only be used inside a function declared with...

5. `event.preventDefault()` in a form submission handler is needed to...


🚀 Chapter Summary:

You have successfully set up a communication channel between "Earth" and "space" and learned how to request telemetry!

  • 🛡️ You solved the "interplanetary interference" problem by configuring CORS on your FastAPI server.
  • 🛰️ Implemented a function to retrieve and display the entire list of spacecraft.
  • 🔭 Created an interface to request data about a specific craft by its ID.

Mission Control is receiving data! In the next chapter, we will move on to active operations: sending commands to create, update, and delete our spacecraft.

📌 Verification:

  • Make sure your FastAPI server is running with CORSMiddleware configured.
  • Check that clicking the "Request Data" button displays the list of ships on the page.
  • Ensure that the search by ID form correctly finds existing crafts and reports an error for non-existing ones.

⚠️ If there are errors:

  • CORS error in the browser console: Either you didn't restart uvicorn after adding CORSMiddleware, or your frontend's address (e.g., http://127.0.0.1:5500) is not added to the origins list.
  • Failed to fetch: Check that your FastAPI server is running and accessible at the address specified in API_BASE_URL.