Skip to main content
In this lesson, we will set up the voting route for our FastAPI application. This endpoint handles likes and unlikes for posts based on the vote direction provided in the request. A vote direction of 1 indicates a “like” while a direction of 0 indicates that the user wants to remove their like. Below is an example payload that the route expects in the request body:
The route is created at /vote and requires only the post ID and vote direction. The user ID is extracted from the JWT token, reducing the parameters needed in the request body. When a user votes, the logic is as follows:
  1. If the vote direction is 1 and the user has already liked the post, the endpoint returns an HTTP 409 Conflict error.
  2. If the vote direction is 0 and the user has not liked the post, the endpoint returns an HTTP 404 Not Found error.
  3. Otherwise, the vote is either added or removed accordingly.

Setting Up the Vote Router

Create a new file vote.py in the routers folder. Start by copying the necessary import statements from one of the other routers:
When you save the file, you might see server log messages similar to:
Next, create an instance of the router with the /vote prefix and the tag “Vote”:
This route uses the POST method to send data for creating or removing votes. The default status is set to 201 (Created). The initial function definition is:

Defining the Vote Schema

Since vote data is received in the request body, defining a Pydantic schema for validation is essential. The schema includes the post ID (an integer) and the vote direction. We use the Pydantic type conint(Le=1) to ensure that the maximum value is 1. Although this approach accepts negative numbers, it is acceptable for now. Future improvements can enforce strictly 0 or 1 values. Below is an example of our Pydantic schemas (including other models for context):
When updating your file, you might see similar logs:

Implementing the Vote Logic

Import the necessary schemas, database utilities, models, and OAuth2 authentication logic as shown below:
Update the vote function to require the vote data via the schema, a database session, and the currently authenticated user:
Always validate that the target post exists before processing any vote changes. This prevents unnecessary database operations and improves the robustness of your endpoint.
A simplified version of the vote logic is as follows:

Testing the Vote Route with Postman

After implementing the voting logic, test the endpoint using Postman. Follow these steps:
  1. Log in to obtain a JWT token.
  2. Create a new POST request for the vote functionality.
  3. Set the request body with the post ID and vote direction (use 1 for liking):
  4. Ensure the Authorization header is set to “Bearer <your_token>”.
  5. For a successful vote, you should receive the response:
If you attempt to like the same post again, the response will be:
To remove a vote, change the direction to 0:
If successful, the confirmation will be:
If the vote does not exist, a 404 error with the detail “Vote does not exist” is returned.
Before testing, you may want to clean your votes table using SQL:
  • Delete all votes:
  • Verify with:

Including the Vote Router in the Main Application

Ensure that your main application file (main.py) includes the vote router. Import the vote router along with the others:
When the vote router is added correctly, you will see similar log entries when the application starts:
Once wired correctly, the /vote endpoint becomes available for use.

Displaying Vote Counts on Posts

A future enhancement is to include the number of votes as a field when retrieving post data. This allows the front-end application to display the like count without issuing an additional query. Implementing this typically involves advanced SQL and SQLAlchemy techniques such as join operations or subqueries.

Handling Votes on Non-existent Posts

If a user attempts to vote on a non-existent post, the endpoint returns a 404 error. This is managed by first querying the posts table using the provided post ID. If the post is not found, an HTTPException with a 404 status code is raised. The updated logic snippet reiterates how to handle this case:

Visual Confirmation

Below are images showing a code editor session and a Postman interface during testing. These images confirm that the changes have been applied correctly and help provide context.
The image shows a Visual Studio Code interface with Python code, including class definitions and a terminal displaying server startup information.
The image shows the Postman application interface with a workspace open, displaying various API request options like GET, POST, and DELETE on the left sidebar. The main area is set up for creating a new GET request, with sections for parameters, headers, and other settings.
By following these steps, you have implemented a robust voting feature in your FastAPI application. For more details on FastAPI and deployment, consider checking out the FastAPI Documentation and exploring additional resources such as Kubernetes Basics. Happy coding!

Watch Video