Share
Explore

API HTML CLIENT


In , we concluded the last excise by writing the API SERVER.

Now let’s make a CLIENT HTML page with forms to demonstrate all the activation paths and use cases for the bookstore APIs.
This will include forms for creating, reading, updating, and deleting both books and authors, along with detailed documentation.
Your finished client web page will look like this:
megaphone

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Bookstore API Demo</title> <style> body { font-family: Arial, sans-serif; line-height: 1.6; padding: 20px; max-width: 800px; margin: 0 auto; } h1, h2, h3 { color: #333; } form { background: #f4f4f4; padding: 20px; margin-bottom: 20px; border-radius: 5px; } input[type="text"], input[type="number"] { width: 100%; padding: 8px; margin-bottom: 10px; } button { background: #333; color: #fff; padding: 10px 15px; border: none; cursor: pointer; } button:hover { background: #444; } #results { background: #e9e9e9; padding: 20px; border-radius: 5px; } .api-doc { background: #f9f9f9; padding: 15px; margin-top: 20px; border-left: 5px solid #333; } </style> </head> <body> <h1>Bookstore API Demo</h1>

<h2>Authors</h2> <h3>Create Author</h3> <form id="createAuthorForm"> <input type="text" id="authorName" placeholder="Author Name" required> <input type="text" id="authorBio" placeholder="Author Bio"> <button type="submit">Create Author</button> </form>
<h3>Get All Authors</h3> <button onclick="getAllAuthors()">Get All Authors</button>
<h2>Books</h2>
<h3>Create Book</h3> <form id="createBookForm"> <input type="text" id="bookTitle" placeholder="Book Title" required> <input type="text" id="bookDescription" placeholder="Book Description"> <input type="number" id="bookYear" placeholder="Published Year" required> <input type="text" id="bookAuthorId" placeholder="Author ID" required> <button type="submit">Create Book</button> </form>
<h3>Get All Books</h3> <button onclick="getAllBooks()">Get All Books</button>
<h3>Get Book by ID</h3> <form id="getBookForm"> <input type="text" id="getBookId" placeholder="Book ID" required> <button type="submit">Get Book</button> </form>
<h3>Update Book</h3> <form id="updateBookForm"> <input type="text" id="updateBookId" placeholder="Book ID" required> <input type="text" id="updateBookTitle" placeholder="New Title"> <input type="text" id="updateBookDescription" placeholder="New Description"> <input type="number" id="updateBookYear" placeholder="New Published Year"> <input type="text" id="updateBookAuthorId" placeholder="New Author ID"> <button type="submit">Update Book</button> </form>
<h3>Delete Book</h3> <form id="deleteBookForm"> <input type="text" id="deleteBookId" placeholder="Book ID" required> <button type="submit">Delete Book</button> </form>
<h2>Results</h2> <div id="results"></div>
<h2>API Documentation</h2> <div class="api-doc"> <h3>Authors API</h3> <h4>POST /api/authors</h4> <p>Create a new author.</p> <p>Body: { name: String, bio: String }</p>
<h4>GET /api/authors</h4> <p>Get all authors.</p>
<h3>Books API</h3> <h4>POST /api/books</h4> <p>Create a new book.</p> <p>Body: { title: String, description: String, publishedYear: Number, authorId: String }</p>
<h4>GET /api/books</h4> <p>Get all books.</p>
<h4>GET /api/books/:id</h4> <p>Get a specific book by ID.</p>
<h4>PATCH /api/books/:id</h4> <p>Update a book.</p> <p>Body: { title?: String, description?: String, publishedYear?: Number, authorId?: String }</p>
<h4>DELETE /api/books/:id</h4> <p>Delete a book.</p> </div>
<script> const API_URL = '/api';
// Helper function to display results function displayResults(data) { document.getElementById('results').innerHTML = '<pre>' + JSON.stringify(data, null, 2) + '</pre>'; }
// Helper function to make API calls async function apiCall(endpoint, method = 'GET', body = null) { const options = { method, headers: { 'Content-Type': 'application/json' }, }; if (body) options.body = JSON.stringify(body);
try { const response = await fetch(`${API_URL}${endpoint}`, options); const data = await response.json(); displayResults(data); return data; } catch (error) { console.error('Error:', error); displayResults({ error: error.message }); } }
// Author functions document.getElementById('createAuthorForm').addEventListener('submit', async (e) => { e.preventDefault(); const name = document.getElementById('authorName').value; const bio = document.getElementById('authorBio').value; await apiCall('/authors', 'POST', { name, bio }); });
async function getAllAuthors() { await apiCall('/authors'); }
// Book functions document.getElementById('createBookForm').addEventListener('submit', async (e) => { e.preventDefault(); const title = document.getElementById('bookTitle').value; const description = document.getElementById('bookDescription').value; const publishedYear = document.getElementById('bookYear').value; const authorId = document.getElementById('bookAuthorId').value; await apiCall('/books', 'POST', { title, description, publishedYear, authorId }); });
async function getAllBooks() { await apiCall('/books'); }
document.getElementById('getBookForm').addEventListener('submit', async (e) => { e.preventDefault(); const id = document.getElementById('getBookId').value; await apiCall(`/books/${id}`); });
document.getElementById('updateBookForm').addEventListener('submit', async (e) => { e.preventDefault(); const id = document.getElementById('updateBookId').value; const title = document.getElementById('updateBookTitle').value; const description = document.getElementById('updateBookDescription').value; const publishedYear = document.getElementById('updateBookYear').value; const authorId = document.getElementById('updateBookAuthorId').value; const updateData = {}; if (title) updateData.title = title; if (description) updateData.description = description; if (publishedYear) updateData.publishedYear = publishedYear; if (authorId) updateData.authorId = authorId; await apiCall(`/books/${id}`, 'PATCH', updateData); });
document.getElementById('deleteBookForm').addEventListener('submit', async (e) => { e.preventDefault(); const id = document.getElementById('deleteBookId').value; await apiCall(`/books/${id}`, 'DELETE'); }); </script> </body> </html>

Comprehensive Bookstore Frontend with API Documentation

This comprehensive HTML page provides a complete interface for interacting with the bookstore API. Here's a breakdown of its features and how to use it:
Structure:
The page is divided into sections for Authors and Books.
Each section contains forms for different API operations (Create, Read, Update, Delete).
There's a Results section to display API responses.
An API Documentation section provides details on each endpoint.
Authors Section:
Create Author: Fill in the name and bio, then submit to create a new author.
Get All Authors: Click the button to retrieve all authors.
Books Section:
Create Book: Fill in the book details, including the author's ID, to create a new book.
Get All Books: Click the button to retrieve all books.
Get Book by ID: Enter a book ID to retrieve a specific book.
Update Book: Enter a book ID and the fields you want to update, then submit to update the book.
Delete Book: Enter a book ID to delete a specific book.
Results:
After each operation, the API response will be displayed in the Results section.
API Documentation:
Provides details on each API endpoint, including the HTTP method, path, and expected request body.
JavaScript Functionality:
The apiCall function handles all API requests, making it easy to add new operations.
Each form submission is handled by an event listener that calls the appropriate API endpoint.
Results are displayed using the displayResults function.
To use this page:
Save it as an HTML file (e.g., index.html) in your project's public directory.
Ensure your Express app is set up to serve static files. Add this to your main app file:
javascript
Copy
app.use(express.static('public'));
Start your Express server and navigate to this page in your browser.
This interface allows students to:
Understand the structure of API requests and responses.
Test all CRUD operations for both books and authors.
See how data is passed to and received from the API.
Understand the relationship between books and authors (via the author ID).

Important usage notes:

Always create an author before creating a book, as you need the author's ID.
When updating a book, you only need to fill in the fields you want to change.
Pay attention to the API responses in the Results section to understand what data is returned.
Refer to the API Documentation section to understand the structure of each API endpoint.
This comprehensive interface serves as both a learning tool and a testing platform for the bookstore API, allowing students to interact with the API and understand its functionality in a practical, hands-on manner.
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.