33.3. Creating Backend Projects
Table of Contents
Starting Your Own Backend Projects
Creating your own backend projects is the fastest way to move from “I understand the theory” to “I can build real systems.” This chapter focuses on how to choose, plan, and execute projects that actually make you better, not just keep you busy.
Why Personal Projects Matter
Personal projects give you:
- Proof of skill: code, APIs, and deployments you can show.
- Practice with the full lifecycle: design, coding, testing, deployment, maintenance.
- Stories for interviews: “I had this bug in production and here is how I fixed it.”
- A safe place to fail and experiment.
Important rule: Treat every serious personal project as if it is a small real-world product:
requirements → design → implementation → tests → deployment → monitoring → iteration.
Choosing the Right Project Ideas
Start Small but Complete
Your goal is not to build something “impressive” on day one. Your goal is to build something simple and finished.
Good beginner criteria:
- Can be built in 1 to 3 weeks of part-time work.
- Has clear inputs and outputs (easy API).
- Can be used by you in real life.
Examples of good starter ideas:
| Project Type | Example Idea | Why It Is Good |
|---|---|---|
| CRUD API | Task manager, notes app, contacts manager | Simple, covers CRUD, auth, pagination |
| Simple business logic | Expense tracker, budget planner | Includes calculations and validations |
| Reference data API | Countries and cities API, movie list API | Read-heavy, simple data model, good for caching practice |
| Learning tools | Flashcards API, vocabulary trainer | Good for relationships and user-specific data |
Avoid at the beginning:
- Full e-commerce with payments and inventory.
- Social networks with complex feeds and notifications.
- Real-time chat with WebSockets plus mobile apps.
You can do those later once you have smaller projects done.
Match Projects to Skills You Want
Pick projects that help you practice specific skills:
| Skill to Practice | Project Feature to Add |
|---|---|
| REST API design | Clean endpoints, versioning, filters, sorting |
| Authentication & authorization | User registration, login, roles (admin, user) |
| Databases & SQL | Relational data, joins, pagination, search |
| Background jobs | Email sending, report generation, scheduled cleanup |
| Caching | Cache frequent reads, invalidate on update |
| File handling | Upload profile images or attachments |
| Testing | Unit tests for logic, integration tests for endpoints |
Pick one main learning focus per project. Do not try to learn everything at once.
Defining Clear Requirements
Before coding, write down what your project should do. Requirements can be simple but must be explicit.
Functional Requirements
These describe what the system does.
Example: “Task Management API”
- Users can register and log in.
- Authenticated users can:
- Create tasks with
title,description,due_date,status. - List their own tasks.
- Update a task.
- Delete a task.
- Filter tasks by status.
- Search tasks by title.
- Admins can:
- View all users.
- View all tasks.
You can write them as user stories:
- “As a user, I want to create tasks so I can track what I need to do.”
- “As a user, I want to filter tasks by status so I can focus on what is pending.”
Non‑Functional Requirements
These describe how the system behaves.
For a beginner project, keep them simple, for example:
- The API must respond within 1 second for typical requests.
- All user passwords must be stored hashed.
- The system must not allow unauthenticated access to protected endpoints.
- The code must have at least some tests for critical features.
- The API must be documented using OpenAPI/Swagger.
Important rule: Never start writing code for a non-trivial project without at least a short written list of functional and non-functional requirements.
Planning the Architecture
You do not need “enterprise architecture,” but you should have a simple, consistent structure.
Decide the Stack
For a typical Python backend project:
- Language: Python
- Framework: FastAPI (or Flask / Django, but this course uses FastAPI)
- Database: PostgreSQL (or SQLite for quick prototypes)
- ORM: SQLAlchemy (or Django ORM if using Django)
- Cache / broker (optional): Redis
Make this explicit in a small “stack” note for your project.
Basic Layering
Even in a small project, separate responsibilities:
- API layer: request handling, HTTP details, serialization.
- Service / business logic layer: core rules, validations, calculations.
- Data access layer: ORM / SQL, repository functions.
Very simple example layout:
project/
app/
api/
v1/
tasks.py
users.py
core/
config.py
security.py
models/
user.py
task.py
services/
task_service.py
user_service.py
db/
session.py
base.py
main.pyYou do not have to create all these files at once. You can start more flat and refactor as it grows.
Design the Data Model
Turn your requirements into tables or collections.
For the Task Management API:
Users table
| Column | Type | Notes |
|---|---|---|
| id | integer (PK) | Primary key |
| text | Unique | |
| password | text | Hashed password |
| is_admin | boolean | Role flag |
| created_at | timestamp | Auto set |
Tasks table
| Column | Type | Notes |
|---|---|---|
| id | integer (PK) | Primary key |
| user_id | integer (FK) | References users.id |
| title | text | Required |
| description | text | Optional |
| status | text | enum: todo, in_progress, done |
| due_date | date | Optional |
| created_at | timestamp | Auto set |
Draw a quick diagram in a note or a document. This prevents a lot of later confusion.
Important rule: Always design your core entities and relationships before writing code that uses them.
Designing the API
Even for a simple project, design the API endpoints up front.
Example Endpoint Design
For the Task Management API:
| Method | Path | Description | Auth required | Notes |
|---|---|---|---|---|
| POST | /auth/register | Register new user | No | Takes email, password |
| POST | /auth/login | Login and get access token | No | Returns JWT or similar |
| GET | /users/me | Get current user info | Yes | |
| GET | /tasks | List tasks | Yes | Filter by status, search by q |
| POST | /tasks | Create task | Yes | |
| GET | /tasks/{task_id} | Get single task | Yes | Only owner or admin |
| PUT | /tasks/{task_id} | Replace task | Yes | |
| PATCH | /tasks/{task_id} | Partially update task | Yes | Optional but nice |
| DELETE | /tasks/{task_id} | Delete task | Yes |
Even a small table like this acts as a mini-contract for what you will build.
Request and Response Models
Define example JSON bodies and responses.
Create task request:
{
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"status": "todo",
"due_date": "2026-09-01"
}Task response:
{
"id": 1,
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"status": "todo",
"due_date": "2026-09-01",
"created_at": "2026-08-28T10:00:00Z"
}These examples help you structure your Pydantic models or serializers later.
Building Incrementally
Do not try to build everything at once. Use small, clear steps.
Step‑by‑Step Roadmap Example
For the Task Management API:
- Project skeleton
- Initialize Git repository.
- Create minimal FastAPI app with
/healthendpoint. - Add basic requirements file.
- Database setup
- Configure SQLAlchemy.
- Create
UserandTaskmodels. - Create initial migration and database (using Alembic, or simple create for first project).
- Auth basics
- Implement registration endpoint.
- Implement login endpoint that returns a token.
- Protect a simple
/users/meendpoint. - Tasks CRUD
- Implement
POST /tasks. - Implement
GET /tasksfor current user. - Implement
GET /tasks/{id}. - Implement
PUT/DELETE /tasks/{id}with ownership check. - Filtering and pagination
- Add
statusfilter and searchqparameter. - Add pagination with
limitandoffsetorpageandpage_size. - Validation and error handling
- Add request validation rules.
- Standardize error responses.
- Tests
- Add basic tests for auth and tasks endpoints.
- Documentation and cleanup
- Ensure OpenAPI docs are clear.
- Refactor code into modules, fix naming, remove dead code.
Each step should be small enough that you can complete it in 1 or 2 sessions.
Important rule: Always aim to keep the project in a “working state.” Do not break everything for days. Implement features in small, testable slices.
Using Git Effectively
For every project, treat Git as part of your skill set, not an afterthought.
Basic Git Practices for Projects
- Initialize a new repository per project.
- Create a
.gitignorefor Python (ignore__pycache__,venv, etc.). - Make small, meaningful commits.
Example commit history for Task Management API:
| Commit message | What changed |
|---|---|
init FastAPI app and health endpoint | Basic app, main.py, first dependency config |
add User and Task models | SQLAlchemy models, database session |
implement user registration | /auth/register, Pydantic models, hashing |
add login and JWT token generation | /auth/login, token creation, settings config |
add create and list tasks endpoints | /tasks GET/POST, service layer |
add ownership checks for task updates | Authorization logic for tasks |
add basic tests for auth and tasks | pytest config and first tests |
This timeline tells a story that interviewers can follow and you can review later.
Writing Minimal but Useful Tests
Testing is covered in its own section in this course. Here we focus on what is specific to personal projects.
What to Test First
Start with:
- Critical business rules.
- Security-sensitive parts.
- Bugs you already found once.
For the Task Management API:
- Registration does not accept duplicate emails.
- Login fails with wrong password.
- A user cannot access another user’s task.
GET /tasksreturns only the current user’s tasks.
Even 5 to 10 tests already make your project more professional and reliable.
Keeping Tests Practical
You do not need 100% coverage. Aim for:
- High coverage on core logic.
- Some coverage on endpoints.
- At least one end-to-end test for a typical flow (register → login → create task → list tasks).
Documenting Your Projects
Documentation is a big part of making your project understandable to others and to future you.
The README
Every project should have a README.md at the root. For a simple backend, include:
- Project description
- “Task Management API built with FastAPI and PostgreSQL.”
- Features
- “User registration and login (JWT auth).”
- “Create, list, update, delete tasks.”
- “Filter and search tasks.”
- Tech stack
- “Python, FastAPI, SQLAlchemy, PostgreSQL, Alembic, pytest, Docker.”
- Setup instructions
- How to clone the repo.
- How to create virtual environment.
- How to set environment variables.
- How to run migrations.
- How to start the server.
- Usage
- Example curl commands for main endpoints.
- Link to Swagger UI (
/docs). - Future improvements
- “Add email notifications.”
- “Add due date reminders.”
- “Add admin panel.”
API Documentation
With FastAPI, you get OpenAPI docs. Make them nicer by:
- Using clear Pydantic models with examples.
- Adding description texts to endpoints.
- Grouping routes logically (for example
/api/v1).
You can also add a simple markdown file docs/api.md with:
- Summaries of main endpoints.
- Auth instructions (how to use the token).
Deploying Your Projects
A project that runs only on your computer is good. A project that runs online is better.
Minimal Deployment Goal
For each serious project, try to:
- Run it in Docker locally.
- Deploy it to a small cloud instance or platform-as-a-service.
- Use environment variables for configuration.
- Use a separate database instance (not SQLite in a local file).
Example deployment path:
- Create
Dockerfileanddocker-compose.yml. - Run app and database locally with Docker.
- Push image to container registry.
- Deploy to a cheap VPS or a managed platform.
- Configure HTTPS and domain for at least one project.
You do not need to do this for every experiment, but do it for the more polished projects that you will show to others.
Reusing Patterns Across Projects
As you build more projects, do not start from zero every time. Create your own “project template” mentally or in code.
Patterns to reuse:
- Folder structure.
- Config and settings pattern.
- Auth pattern (JWT, middleware).
- Logging configuration.
- Error handling format.
- Testing setup.
For example, you can have a fastapi-template repository with:
- Basic
main.py. - Settings via
pydantic-settings. - Database session boilerplate.
- JWT utilities.
- Example health check and
/users/meendpoint.
Then for each new project:
- Copy or clone that template.
- Rename package and project.
- Remove example endpoints.
- Start implementing new business logic.
This speeds you up and builds consistency between projects.
Growing Project Complexity Over Time
You do not need one “huge” project. It is better to build multiple projects of increasing complexity.
Possible progression:
- Project 1: Notes API (no auth, SQLite)
- Simple CRUD.
- Focus on REST and database basics.
- Project 2: Task Manager (auth, PostgreSQL, tests)
- User accounts.
- Roles (admin / user).
- Basic tests.
- Project 3: URL Shortener (Redis, rate limiting)
- Simple business logic.
- Caching.
- Rate limiting.
- Project 4: Simple E-commerce backend (cart, orders)
- Multiple entities, relationships.
- Payments simulation (no real gateway at first).
- Background processing for order emails.
- Project 5: Real “portfolio” app
- Best of everything you learned.
- Fully documented and deployed.
Each new project reuses lessons from previous ones and adds one or two new major concepts.
Learning from Your Own Code
Every project is also a learning record.
After Finishing a Project
Ask yourself:
- What part was hardest?
- Where did bugs appear most often?
- Which parts of the code look messy now?
- What would I change if I started again?
You can do a simple “postmortem” document:
Project: Task Management API
What went well:
- Clear endpoints
- Simple data model
What went wrong:
- Mixed business logic in API layer
- Poor test coverage at the beginning
Improvements for next project:
- Introduce service layer earlier
- Write tests sooner
- Plan error responses up frontThis is how professionals improve across projects.
Turning Projects into Portfolio Pieces
When you have a few solid backend projects:
- Put them on GitHub or GitLab.
- Add a short description and tech stack in the repo.
- Tag or pin the most important repos.
- Optionally write a short blog post or README section that tells:
- The problem.
- The design.
- Interesting technical decisions.
- Lessons learned.
This connects directly to the “Building a Portfolio” chapter and will be very useful when you prepare for interviews.
Key checklist for a strong backend project:
- Clear requirements and scope.
- Simple but explicit data model.
- Thoughtful API design.
- Clean Git history.
- Basic tests for critical features.
- Good README and API docs.
- At least one deployed or Dockerized version.
Even if the project is small, this combination is what shows you can think and work like a backend engineer.
By following this approach for each new project, you will steadily turn your backend knowledge into real, demonstrable skills.
Views: 9
KAHIBARO