Skip to main content
In this article, we demonstrate how to retrieve an individual post from a PostgreSQL database using FastAPI. We will build a secure GET endpoint that fetches a post by its ID using a parameterized SQL query, significantly reducing the risk of SQL injection attacks. Additionally, we briefly cover the DELETE endpoint for completeness. Below is the step-by-step evolution of the implementation along with key points and code examples.

Step 1: Basic GET and DELETE Endpoints

Initially, you define the endpoints for retrieving and deleting posts. Starting with a basic structure, the endpoints might look like this:
When executing the application, you may see console output similar to the following:

Step 2: Incorporating SQL Queries

To fetch posts from the database, the cursor object is used to execute SQL queries. An initial approach might involve fetching all posts:
This approach retrieves all records from the posts table. Later, we will optimize the query to ensure that only the specified post is selected.

Step 3: Filtering Posts by the Given ID

Instead of retrieving all posts, we update the SQL statement to fetch a single record that matches the provided ID. For testing purposes, you might initially hardcode the query with a known ID (for example, 1):
After verifying the query using a direct SQL command like SELECT * FROM posts; in your database client, you can proceed to parameterize the query.

Step 4: Parameterizing the SQL Query

To safeguard against SQL injection, replace the hardcoded ID with the provided path parameter through parameter substitution. Although the path parameter is already validated as an integer, it’s converted to a string for compatibility with the SQL driver. The %s placeholder is used in the SQL statement:
Be sure to include an extra comma in the tuple (i.e., (str(id),)) to prevent unexpected issues with parameter tuple assignment.

Step 5: Final Cleaned-Up Code

After removing debugging statements and ensuring robust input validation, the final version of the GET endpoint is as follows. The DELETE endpoint is also updated for completeness:
When the GET endpoint is called for an existing post (for example, with an ID of 1), the JSON response may appear as:
In contrast, when a post is not found (for example, an ID of 5), the API returns an error response:

Additional Notes

During development, you might encounter an error such as:
This error should resolve once the SQL query correctly uses parameter substitution. If issues persist with the parameter tuple, double-check for the extra comma, ensuring it is written as (str(id),). Happy coding!

Watch Video