Project Overview
In this project, we’ll build a simple Employee Management System. To keep the focus on FastAPI concepts, we’ll store data in Python lists instead of a database. By completing this project, you’ll learn how to build a real REST API using FastAPI.What You’ll Build
Our application manages two resources:- Employees
- Departments
APIs We’ll Build
Employee APIs
Department APIs
Later we’ll enhance the Employee API with filtering.
Example:
Concepts We’ll Learn
During this project we’ll gradually introduce:- APIRouter
- Dependency Injection
- Request Models
- Response Models
- Request Body Validation
- Path Parameter Validation
- Query Parameter Validation
- Exception Handling
- HTTP Status Codes
Project Structure
Development Plan
We’ll build the project one feature at a time.
At every step:
- Read the task.
- Try it yourself.
- Test it in Swagger UI.
- Open the solution only if needed.
Step 2 - Create the Models
Task
Before writing any APIs, define the data our application will manage. Based on the project requirements, create models for the following resources. Try implementing them yourself before opening the solution.Employee Structure
Example
Department Structure
Example
Models to Create
Before opening the solution, think about this:
Should the client send the employee id while creating a new employee?If your answer is No, which model should contain the
id field?
Solution
Employee Request Model
Used while creating or updating an employee. Notice that the client does not send the employee ID.EmployeeRequest
EmployeeRequest
Employee Business Model
Represents an employee inside the application.Employee
Employee
Employee Response Model
Returned to the client.EmployeeResponse
EmployeeResponse
Department Request Model
Used while creating or updating a department.DepartmentRequest
DepartmentRequest
Department Business Model
Represents a department inside the application.Department
Department
Department Response Model
Returned to the client.DepartmentResponse
DepartmentResponse
Model Flow
Why Three Models?
For example, when creating an employee, the client sends:
id. It is generated by the application.
Key Takeaways
- Use Request Models to validate client input.
- Use Business Models to represent data inside the application.
- Use Response Models to control API responses.
- Separating models keeps the application clean and makes it easier to evolve as requirements change.
Step 3 - Create the In-Memory Database
Task
Before implementing the APIs, we need a place to store our data. Instead of using a real database, we’ll use Python lists as an in-memory database. This allows us to focus on learning FastAPI without worrying about database configuration. Later, we can replace these lists with a real database without changing the API design.Data Structure
We’ll maintain two collections:- EMPLOYEES – Stores employee records.
- DEPARTMENTS – Stores department records.
department_id should refer to an existing department.
Sample Data
Create a file named data.py.Data to Store
Departments
Create the following department objects.Employees
Create the following employee objects.
Using these values, create two Python lists:
DEPARTMENTSEMPLOYEES
Department and Employee).
Try creating the lists yourself before viewing the solution.
Sample Data
Create a file named data.py.data.py
data.py
Step 4 - Create the Routers
Task
Create separate routers for managing employees and departments. Instead of placing every endpoint insidemain.py, we’ll organize related endpoints into separate files.
This approach makes the application easier to read, maintain, and extend.
By the end of this step, your project structure should look like this:
Router Responsibilities
Each router is responsible for a single resource.Create the Employee Router
Create a file named routers/employees.py. Try creating the router yourself before viewing the solution.employees.py
employees.py
Create the Department Router
Create a file named routers/departments.py. Try creating the router yourself before viewing the solution.departments.py
departments.py
Register the Routers
Now connect both routers to the FastAPI application. Open main.py and register them. Try implementing it before viewing the solution.main.py
main.py
Understanding APIRouter
The router is created using:prefix
The prefix is automatically added to every endpoint inside the router. For example,tags
Thetags parameter groups related endpoints together in the Swagger UI.
Instead of displaying all APIs in one long list, Swagger organizes them into sections.
What We’ve Accomplished
At this stage:- The application is modular.
- Employee APIs have their own router.
- Department APIs have their own router.
- Both routers are registered with the FastAPI application.
- Swagger will automatically organize the endpoints by resource.
Step 5 - Implement the Get All Employees API
Task
Implement an API to retrieve all employees. Requirements- Method:
GET - URL:
/employees - Use
Depends(get_employee_data) - Return all employees
- Use
list[EmployeeResponse]as the response model
employees.py
employees.py
Test
- Status Code: 200 OK
- Returns all employees.
Step 6 - Implement the Get Employee by ID API
Task
Implement an API to retrieve a single employee using the employee ID. Requirements- Method:
GET - URL:
/employees/{emp_id} - Use
Depends(get_employee_data) - Use
Path()validation - Return
EmployeeResponse - Return 404 Not Found if the employee does not exist
employees.py
employees.py
Test
Step 7 - Implement the Create Employee API
Task
Implement an API to add a new employee. Requirements- Method:
POST - URL:
/employees - Accept
EmployeeRequestas the request body - Use
Depends(get_employee_data) - Generate the next employee ID automatically
- Return the newly created employee
- Use
EmployeeResponseas the response model - Return 201 Created
employees.py
employees.py
Test
Sample Request
Sample Response
Step 8 - Implement the Update Employee API
Task
Implement an API to update an existing employee. Requirements- Method:
PUT - URL:
/employees/{emp_id} - Accept
EmployeeRequestas the request body - Use
Path()validation - Use
Depends(get_employee_data) - Return the updated employee
- Return 404 Not Found if the employee does not exist
employees.py
employees.py
Test
Sample Request
Sample Response
Step 9 - Implement the Delete Employee API
Task
Implement an API to delete an existing employee. Requirements- Method:
DELETE - URL:
/employees/{emp_id} - Use
Path()validation - Use
Depends(get_employee_data) - Delete the employee if found
- Return 204 No Content
- Return 404 Not Found if the employee does not exist
employees.py
employees.py
Test
Sample Request
Expected Response
Step 10 - Filter Employees by Department
Task
Enhance the Get All Employees API to optionally filter employees by department. Requirements- Method:
GET - URL:
/employees - Accept an optional
department_idquery parameter - Use
Query()validation - Return all employees if no department is specified
- Return only matching employees if
department_idis provided
employees.py
employees.py
Test
Sample Requests
Step 11 - Search Employees by Name
Task
Enhance the Get All Employees API to search employees by name. Requirements- Method:
GET - URL:
/employees - Accept an optional
namequery parameter - Use
Query()validation - Perform a case-insensitive search
- Return all employees if no name is specified
employees.py
employees.py
Test
Sample Requests
Step 12 - Filter Employees by Minimum Age
Task
Enhance the Get All Employees API to filter employees based on a minimum age. Requirements- Method:
GET - URL:
/employees - Accept an optional
min_agequery parameter - Use
Query()validation - Return employees whose age is greater than or equal to the specified age
- Return all employees if
min_ageis not specified
employees.py
employees.py
Test
Sample Requests
Step 13 - Add Pagination and Sorting
Task
Enhance the Get All Employees API to support pagination and sorting. Requirements- Method:
GET - URL:
/employees - Accept
skipquery parameter - Accept
limitquery parameter - Accept
sortquery parameter - Sort by either name or salary
- Return the requested page of employees
employees.py
employees.py
Test
Sample Requests
Step 15 - Implement the Department APIs
Task
Implement the Department APIs using the concepts you’ve learned in the Employee module. The implementation should follow the same approach.- Use
APIRouter - Use
Depends() - Use
DepartmentRequest - Use
DepartmentResponse - Use
Path()validation - Use
HTTPException - Return appropriate HTTP status codes
APIs to Implement
Try implementing all the APIs before viewing the solution.
departments.py
departments.py