Creating a Front-end
Build a simple front-end that consumes your REST API — fetch and display data from the API in the browser.
Creating a Front-end
Your REST API is complete — it handles GET, POST, PUT, and DELETE requests with MongoDB. Now it is time to build a front-end that consumes the API and displays the data in the browser.
Setting Up
We will create a simple HTML page that uses the Fetch API to communicate with the REST API. No front-end framework is needed for this — just plain HTML, CSS, and JavaScript.
Serving Static Files
// index.js — add static file serving
app.use(express.static('public'));
Create a public/ folder in your project root. Express will serve any files in this folder. Navigating to http://localhost:3000 will load public/index.html.
The HTML Page
<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ninja API</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<h1>Ninja Directory</h1>
<form id="ninja-form">
<input type="text" id="name" placeholder="Ninja name" required>
<input type="number" id="rank" placeholder="Rank (1-10)" min="1" max="10" required>
<button type="submit">Add Ninja</button>
</form>
<div id="ninja-list"></div>
</div>
<script src="app.js"></script>
</body>
</html>
Fetching Data from the API
// public/app.js
// GET all ninjas and display them
async function loadNinjas() {
const response = await fetch('/api/ninjas');
const ninjas = await response.json();
const list = document.getElementById('ninja-list');
list.innerHTML = ninjas.map(ninja => `
<div class="ninja-card">
<h3>${ninja.name}</h3>
<p>Rank: ${ninja.rank}</p>
<button onclick="deleteNinja('${ninja._id}')">Delete</button>
</div>
`).join('');
}
// Load ninjas on page load
loadNinjas();
The Fetch API
| Method | Fetch Call |
|---|---|
| GET | fetch('/api/ninjas') |
| POST | fetch('/api/ninjas', { method: 'POST', headers, body }) |
| PUT | fetch('/api/ninjas/id', { method: 'PUT', headers, body }) |
| DELETE | fetch('/api/ninjas/id', { method: 'DELETE' }) |
Posting Data (Creating a Ninja)
document.getElementById('ninja-form').addEventListener('submit', async (e) => {
e.preventDefault();
const name = document.getElementById('name').value;
const rank = document.getElementById('rank').value;
const response = await fetch('/api/ninjas', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, rank: Number(rank) }),
});
if (response.ok) {
document.getElementById('name').value = '';
document.getElementById('rank').value = '';
loadNinjas(); // Refresh the list
}
});
Deleting a Ninja
async function deleteNinja(id) {
const response = await fetch(`/api/ninjas/${id}`, {
method: 'DELETE',
});
if (response.ok) {
loadNinjas(); // Refresh the list
}
}
CORS Considerations
If your front-end is served from a different origin (different port or domain), you need CORS:
npm install cors
const cors = require('cors');
app.use(cors());
Since we are serving the front-end from the same Express server (express.static), CORS is not needed. But when using a separate React dev server (next episode), CORS is required.
Key Takeaways
express.static('public')serves HTML, CSS, and JS files from thepublic/folder- The Fetch API sends HTTP requests from the browser —
fetch()returns a Promise - Use
response.json()to parse the JSON response body - POST and PUT requests need
method,headers(Content-Type), andbody(JSON string) - After creating or deleting data, refresh the displayed list by calling the GET endpoint again
- CORS is needed when the front-end and API are on different origins