Chapter 6.1: Connecting FastAPI to the Frontend
Study Time: 30 minutes
1. Return to the "Hyperdrive": Comparing Protocols
In the last chapter, we docked our Mission Control Center (frontend) with the "ISS" (Laravel API). Now we will return to our superluminal fighter (FastAPI) and perform the same operation.
The goal of this chapter is not just to repeat the steps, but to compare the two approaches. It's as if the same Dragon spacecraft first docked with the ISS, and then with the Chinese Tiangong station. The docking node is the same (REST), but there may be nuances in procedures and port locations.
💡 Space Analogy:
The process is the same: fly up, align, dock. But for the "ISS" it was necessary to use the
/api/planets
port, and for "Tiangong" — the/spaceships
port. Our operator at Mission Control must know these details for the mission to be successful.
2. Preparing the "Fighter" (FastAPI) for Docking
We already did this in Chapter 4.2, but let's make sure everything is in place.
Step 1: Start the FastAPI Server
- Stop the Laravel server if it is running (to avoid port conflicts).
- Open a terminal in your FastAPI project folder.
-
Activate the virtual environment:
- Windows:
.\venv\Scripts\Activate.ps1
- macOS / Linux:
source venv/bin/activate
- Windows:
-
Start the server:
The server will be available athttp://127.0.0.1:8000
.
Step 2: Check CORS Settings in main.py
Make sure your FastAPI project has the CORSMiddleware
configured that we added earlier. It should allow requests from your frontend address.
# main.py
from fastapi.middleware.cors import CORSMiddleware
# ...
origins = [
"http://127.0.0.1:5500", # Live Server address
"null", # For file:///
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# ...
3. Reconfiguring the Mission Control "Antenna" Back to FastAPI
Now for the interesting part — the minimal changes that need to be made to our JavaScript to get it working with FastAPI again.
Step 1: Change the Base URL
Open api.js
and revert API_BASE_URL
to its original value.
// api.js
// Specify the URL of our FastAPI API
const API_BASE_URL = 'http://127.0.0.1:8000'; // <-- Without /api!
// ... rest of the apiRequest code ...
Step 2: Adapting to the FastAPI Response Structure
Recall that our GET /spaceships
in FastAPI returns a simple array, not an object with pagination. This means we need to revert the fetchAndDisplayFleet
code to its original form.
Change the fetchAndDisplayFleet
function in app.js
:
// app.js
async function fetchAndDisplayFleet() {
try {
fleetListContainer.innerHTML = '<p>Loading telemetry from FastAPI...</p>';
const ships = await apiRequest('/spaceships'); // <-- Request to /spaceships
// In FastAPI we have a simple array, so the .data key is not needed!
fleetListContainer.innerHTML = '';
if (ships.length === 0) {
fleetListContainer.innerHTML = '<p>There are no vehicles in the registry.</p>';
return;
}
ships.forEach(ship => {
// Return our original function for creating cards
const card = createShipCard(ship);
fleetListContainer.appendChild(card);
});
} catch (error) {
fleetListContainer.innerHTML = `<p style="color: #ff6b6b;">Error loading fleet: ${error.message}</p>`;
}
}
// Original function for creating ship cards
function createShipCard(ship) {
const card = document.createElement('div');
card.className = 'card';
card.innerHTML = `
<h3>${ship.name} (ID: ${ship.id})</h3>
<p>Type: ${ship.type}</p>
<p>Launch Year: ${ship.launch_year}</p>
<p>Status: ${ship.status}</p>
<div class="card-actions">
<button class="edit-btn" data-ship-id="${ship.id}">Edit</button>
<button class="delete-btn" data-ship-id="${ship.id}">Decommission</button>
</div>
`;
return card;
}
Step 3: Checking CRUD Operations
Since our Pydantic models in FastAPI and the fields in the HTML form match (name
, type
, launch_year
, status
), the handleSaveShip
and handleDeleteShip
functions should work without changes, as they are already aimed at the /spaceships
endpoint.
4. Comparison Summary: What Does This Mean for a Frontend Developer?
- Universality of REST: You have clearly seen that for the frontend it does not matter what the backend is written in (PHP/Laravel or Python/FastAPI), as long as it follows the principles of REST.
- Importance of Documentation: The main differences were in the endpoint URLs and the structure of JSON responses. This is exactly what should be described in the API documentation. Without it, the frontend developer will be working "blind".
- Frontend Flexibility: Your JavaScript code should be flexible enough to easily adapt to different data formats (for example, checking if there is a
data
key, or if it is just an array).
Conclusion: The skill of working with a REST API is a universal key that opens the door to interacting with any modern backend.
Reinforcement Quiz
🚀 Chapter Summary:
You have successfully switched the "communication protocols" of your Mission Control and in practice compared working with two different backend systems.
- ✅ You have reinforced the skill of configuring
API_BASE_URL
to switch between servers. - ✅ You understand how important the response structure is (
data
vs a simple array) and how to adapt the frontend to it. - ✅ You have realized that a good frontend developer must be prepared to work with any RESTful API by carefully studying its documentation.
Universal docking skill acquired! Now that we know how to set up basic communication, it's time to talk about more complex protocols — CORS, authentication, and security.
📌 Check:
- Make sure your FastAPI server is running.
- Make sure you have reverted
API_BASE_URL
and the response handling logic inapp.js
to the FastAPI version.- Check that your frontend is again correctly performing all CRUD operations with the FastAPI backend.
⚠️ If errors:
- CORS error: Make sure the FastAPI server is running with the correct CORS settings.
Cannot read properties of undefined (reading 'length')
error: You may have forgotten to remove the access to.data
fromresponseData
.- 404 Not Found: Check
API_BASE_URL
— FastAPI does not have an/api
prefix.