Connect Your FastAPI Backend to a JavaScript Frontend
In this tutorial, you will learn how to integrate a JavaScript frontend with your existing FastAPI backend to enable full CRUD (Create, Read, Update, Delete) functionality directly from the web browser. We will cover adding forms, handling user input, making API requests using the Fetch API, and displaying feedback to the user, including success and error messages. You’ll also learn how to modify your backend to ensure consistent data ordering and prepare it for future authentication features.
Prerequisites
- A working FastAPI backend with at least one user and some existing posts from previous tutorials.
- Basic understanding of HTML, JavaScript, and Bootstrap.
- Node.js and npm/yarn installed if you need to set up a project structure for static files.
Step 1: Add a “New Post” Button and Modal to the Layout
To make the post creation process accessible from any page, we’ll add a “New Post” button to the base layout template. This button will trigger a Bootstrap modal containing a form for creating new posts.
- Open your base layout file (e.g.,
layout.html). - Locate your navigation bar.
- Add a new button before your login/register buttons. This button should have attributes to trigger a Bootstrap modal (e.g.,
data-bs-toggle="modal"anddata-bs-target="#createPostModal"). - Add the HTML structure for the
createPostModalbelow your footer. This modal will contain a form with input fields for the post’s title and content. - Crucially, the form should not have
actionormethodattributes, as we will handle submission via JavaScript.
Step 2: Implement Success and Error Modals
To provide user feedback, we’ll add two more modals: one for success messages and one for error messages. These will also be placed in the base layout file to be accessible globally.
- After the
createPostModalin yourlayout.htmlfile, add two new Bootstrap modals: one for success and one for errors. - The success modal should have a distinct visual indicator (e.g., a green header) and a paragraph with an ID like
successMessageto display the success notification. - The error modal should have a similar distinct visual indicator (e.g., a red header) and a paragraph with an ID like
errorMessageto display error details.
Step 3: Create JavaScript Utility Functions
To avoid repeating code, we’ll create a JavaScript utility module to hold reusable functions for handling modals and parsing API error responses.
- In your static files directory (e.g.,
static/js/), create a new file namedutils.jsif it doesn’t exist. - Add the following utility functions to
utils.js:getErrorMessage(error): This function parses API error responses, handling both simple string messages and more complex validation error objects, returning a user-friendly message.showModal(modalId): A helper to display a Bootstrap modal given its ID.hideModal(modalId): A helper to hide a Bootstrap modal given its ID.
- Ensure these functions are exported so they can be imported into other JavaScript files.
Step 4: Wire Up the Create Post Form with JavaScript
Now, we’ll add the JavaScript logic to handle the submission of the create post form, send data to the FastAPI backend, and display the appropriate feedback.
- In your
layout.htmlfile, add a<script type="module">block just before the closing</body>tag. - Import the utility functions from
utils.js. - Get a reference to the
createPostFormusing its ID. - Add an event listener for the
submitevent on the form. - Inside the event listener, call
event.preventDefault()to stop the default browser submission. - Gather the form data using
new FormData(form)and convert it into a JavaScript object. - Temporarily add a hard-coded
user_idto the data. This will be replaced with authentication later. - Use the Fetch API to send a
POSTrequest to your/api/postsendpoint. Set theContent-Typeheader toapplication/jsonand stringify the form data for the request body. - Handle the response:
- If the response is successful (e.g., status code 200-299): Parse the JSON, display a success message in the success modal, hide the create post modal, show the success modal, and clear the form. Add an event listener to the success modal to reload the page when it’s closed.
- If the response is an error: Parse the error message using
getErrorMessage, hide the create post modal, and show the error modal with the detailed message. - Catch any network errors and display a generic network error message.
Step 5: Update Backend for Consistent Post Ordering
By default, posts might be returned in creation order, which isn’t ideal for a feed. We need to ensure the newest posts appear first by updating the backend queries.
- Identify all backend routes that return lists of posts (e.g., the home route, API post list route, user post routes).
- In each of these routes, modify the SQLAlchemy query to include an
order_by()clause. - Use
models.Post.date_posted.desc()to sort the posts by their creation date in descending order (newest first). - Save the changes and test by creating a new post from the frontend; it should appear at the top of the list.
Step 6: Add Edit and Delete Functionality
We’ll now implement the ability to edit and delete existing posts, again using modals and JavaScript to interact with the API.
- In your
post.htmltemplate (or equivalent for individual post views):- Remove any existing placeholder edit/delete buttons and the associated placeholder delete modal.
- Add new edit and delete buttons. These buttons should be conditionally displayed (e.g., only if the post’s
user_idmatches a specific temporary ID, which will be replaced by proper authentication later). - These buttons should also use Bootstrap’s modal trigger attributes to open specific modals for editing and deleting.
- Add the HTML structure for an
editPostModal. This modal should be similar to the create modal but include:- A hidden input field to store the
post_id. - The title and content input fields should be pre-filled with the current post’s data.
- The form should have a unique ID (e.g.,
editPostForm).
- A hidden input field to store the
- Add the HTML structure for a
deleteConfirmationModal. This modal should contain a confirmation message and a button to trigger the delete action. It does not need to be a form. - In your
post.htmltemplate, add a{% block scripts %}...{% endblock %}section after the main content block. - Inside this script block, add JavaScript to handle:
- Getting the
post_id(often available via template variables). - Adding a
submitevent listener to theeditPostForm. Prevent default submission, gather form data, and send aPATCHrequest to/api/posts/{post_id}. Handle success (show success modal, reload on close) and error responses. - Adding a
clickevent listener to the delete confirmation button. Send aDELETErequest to/api/posts/{post_id}. On successful deletion (status code 204), redirect to the homepage. Handle errors by showing the error modal.
- Getting the
Step 7: Test All Functionality and Error Handling
With all the pieces in place, thoroughly test the create, edit, and delete operations, as well as the error handling mechanisms.
- Reload your application in the browser.
- Test creating a new post using the “New Post” modal. Verify it appears correctly and is sorted to the top.
- Test editing an existing post. Ensure the modal pre-fills correctly and the changes are saved and reflected after the page reloads.
- Test deleting a post. Confirm the confirmation modal appears and that the post is removed upon confirmation.
- Test error scenarios:
- Attempt to create a post with a title exceeding the maximum character limit (e.g., 100 characters). Verify that the error modal displays the validation error message from the backend.
- Simulate other potential errors (e.g., network issues, though harder to test directly) to ensure generic error messages are shown.
Conclusion and Next Steps
You have now successfully connected your FastAPI backend to a JavaScript frontend, enabling users to perform all CRUD operations directly from their browser. This approach leverages modals for a seamless user experience, keeping users on their current page. The separation of concerns between the backend API and the frontend presentation makes your backend reusable for other clients like mobile or desktop applications.
The next crucial step will be implementing authentication. Currently, the `user_id` is hard-coded, leaving your application insecure. Future tutorials will cover user registration, login using JSON Web Tokens (JWT), and automatically associating actions with the authenticated user, replacing the temporary scaffolding with robust security measures.
Source: Python FastAPI Tutorial (Part 9): Frontend Forms – Connecting JavaScript to Your API (YouTube)