Skip to main content
In this article, we explain how to define Pydantic schema models to shape API responses effectively when using FastAPI. Learn how to modify responses to include only the fields needed by the client, thereby excluding sensitive or unnecessary data like passwords or internal IDs. FastAPI’s seamless integration with SQLAlchemy and Pydantic helps you tailor responses for better clarity and security. Below is our initial code for handling GET and POST requests for “posts” using SQLAlchemy. Notice the commented-out raw SQL queries alongside the ORM-based approach:
Console output indicates that the application started successfully:
Currently, our endpoints return a dictionary with the key “data” wrapping the posts or a list of posts. However, this extra nesting might be unnecessary. To simplify responses, we can remove the “data” key and return the post or list of posts directly. For example:
The updated console output now resembles:
If you need to filter out sensitive attributes (e.g., a user’s password) before sending data to the client, consider modifying your endpoint responses to return only the required fields.

Defining the Response Schema with Pydantic

Next, we define the response schema using Pydantic models. Initially, Pydantic models define the schema for creating posts (data input from the user):
When FastAPI returns a response, you might want to include only selected fields (e.g., title, content, published) and optionally additional fields such as an ID or a creation timestamp that exists in your database. We create a new model for responses as shown below:
Enabling ORM mode tells Pydantic to read attributes from an ORM object (such as a SQLAlchemy model) by treating them as a dictionary. This prevents errors like:

Using the Response Schema in the Create Endpoint

Once a post is created, the updated endpoint uses the response model:
A sample JSON response after creating a post:
Even though PostgreSQL stores additional fields like the ID and creation timestamp, you can control which fields are sent to the client by updating the Pydantic model. For example, to include the ID and creation timestamp in the response:
The API response will now include all defined fields:
If certain fields (such as created_at) should not be exposed, remove them from the response schema.

Leveraging Inheritance to Reduce Redundancy

You can streamline your code by leveraging inheritance. Since the fields for title, content, and published are already defined in PostBase, extend it in your response model to add only the new fields:

Updating Other Endpoints with the Response Model

Root and Posts Endpoints

Here’s how you can update the endpoints to remove unnecessary nesting and to adopt the response model approach:
Console logs confirm that GET and POST operations function as expected:

Retrieving and Updating a Single Post

To retrieve a single post, ensure you specify the response model in your endpoint:
Similarly, update the endpoint for modifying a post:

Handling a List of Posts

When returning a list of posts, update the response model to handle lists effectively by importing List from the typing module:
Console output confirms that the GET request returns a list of posts:

Summary

By explicitly defining your response schema using Pydantic models and enabling ORM mode, you achieve:
  • Better control over the fields exposed in API responses.
  • Reduced redundancy via inheritance and clearer API design.
  • Improved performance and security by returning only necessary data.
Implementing these practices in your FastAPI projects ensures cleaner, more maintainable code and enhances the overall developer and client experience.

Watch Video