AWS Builder Center

Building a FastAPI Backend with MongoDB: A Beginner-Friendly Guide

Learn how to build a REST API using FastAPI and MongoDB, configure CORS and environment variables, create API routes, and run the backend locally.

Building a FastAPI Backend with MongoDB: A Beginner-Friendly Guide

Modern applications need a reliable backend to handle user accounts, data storage, authentication, and communication between the frontend and database. In this article, we will build a simple backend using FastAPI and MongoDB and understand how the different components work together.

Introduction

FastAPI is a modern Python framework for building APIs. It is fast, easy to learn, and provides automatic interactive API documentation.
MongoDB is a NoSQL database that stores data in flexible JSON-like documents. Combining FastAPI with MongoDB provides a lightweight and scalable approach for building web application backends.
The basic architecture looks like this:
1
2
3
4
5
6
7
8
9
Frontend
|
| HTTP Requests
v
FastAPI Backend
|
| Database Operations
v
MongoDB
For example, when a user registers:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
User
|
v
Frontend Registration Form
|
v
POST /api/auth/register
|
v
FastAPI
|
v
Validate User Data
|
v
MongoDB
|
v
User Created

1. What is FastAPI?

FastAPI is a Python framework designed for creating APIs.
Some important features include:
  • High performance
  • Simple Python syntax
  • Automatic API documentation
  • Type hints
  • Request validation
  • Support for asynchronous programming
  • Easy integration with databases
A basic FastAPI application looks like this:
1
2
3
4
5
6
7
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def home():
return {"message": "Hello, World!"}
Run the application using:
1
uvicorn main:app --reload
The API will be available at:
1
http://127.0.0.1:8000
FastAPI also automatically provides interactive documentation at:
1
http://127.0.0.1:8000/docs

2. What is MongoDB?

MongoDB is a document-oriented NoSQL database.
Instead of storing data in traditional rows and columns, MongoDB stores documents inside collections.
For example, a user document can look like:
1
2
3
4
5
{
"username": "roshan",
"email": "roshan@example.com",
"score": 100
}
A MongoDB database can contain multiple collections:
1
2
3
4
5
signbridge
├── users
├── challenges
├── leaderboard
└── game_data
This structure makes MongoDB useful for applications where data may change or grow over time.

3. Project Structure

A FastAPI project can be organized into multiple modules instead of putting everything into one file.
For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
backend/
│
├── app/
│ ├── main.py
│ ├── config.py
│ ├── database.py
│ │
│ └── routers/
│ ├── auth.py
│ ├── users.py
│ ├── challenges.py
│ └── leaderboard.py
│
├── requirements.txt
├── .env
└── README.md
This organization makes the project easier to maintain and expand.

4. Setting Up the Python Environment

First, create a virtual environment:
1
python -m venv venv
Activate it on macOS or Linux:
1
source venv/bin/activate
On Windows:
1
venv\Scripts\activate
Then install the required packages:
1
pip install fastapi uvicorn pymongo pydantic-settings python-dotenv
A requirements.txt file can be used to store dependencies:
1
2
3
4
5
fastapi
uvicorn
pymongo
pydantic-settings
python-dotenv
Install them using:
1
pip install -r requirements.txt

5. Configuring Environment Variables

Sensitive configuration values should not be hard-coded directly into the application.
Create a .env file:
1
2
3
4
5
6
7
MONGODB_URI=mongodb://localhost:27017
MONGODB_DB_NAME=signbridge

JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=10080

CORS_ORIGINS=http://localhost:5500
Environment variables make it easier to use different configurations during development and deployment.

6. Connecting FastAPI to MongoDB

A database module can manage the MongoDB connection.
Example:
1
2
3
4
5
6
7
8
from pymongo import AsyncMongoClient
from app.config import settings

client = AsyncMongoClient(settings.mongodb_uri)

db = client[settings.mongodb_db_name]

users_collection = db["users"]
The application can then use this collection to create and retrieve user data.
For example:
1
2
3
4
await users_collection.insert_one({
"username": "roshan",
"email": "roshan@example.com"
})

7. Creating API Routes

API routes define how the frontend communicates with the backend.
For example:
1
2
3
4
5
6
7
from fastapi import APIRouter

router = APIRouter(prefix="/api/users")

@router.get("/")
async def get_users():
return {"message": "User list"}
The endpoint becomes:
1
GET /api/users/
A frontend application can call this endpoint using an HTTP request.

8. User Registration

A registration endpoint receives information from the frontend.
Example:
1
2
3
4
5
6
7
8
9
10
from fastapi import APIRouter

router = APIRouter(prefix="/api/auth")

@router.post("/register")
async def register_user(user: dict):
return {
"message": "User registered successfully",
"user": user
}
The frontend can send:
1
2
3
4
5
{
"username": "roshan",
"email": "roshan@example.com",
"password": "example-password"
}
In a real application, passwords should never be stored as plain text. They should be securely hashed before being stored in MongoDB.

9. Authentication

Authentication allows the backend to identify users.
A common approach is JSON Web Token (JWT) authentication.
The general process is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Login
|
v
FastAPI
|
v
Validate Credentials
|
v
Generate JWT
|
v
Send Token to Frontend
|
v
Frontend Stores Token
|
v
Token Sent With Future Requests
For example:
1
Authorization: Bearer <token>
The backend can validate the token before allowing access to protected endpoints.

10. CORS Configuration

When the frontend and backend run on different origins, the browser can block requests unless the backend allows the frontend origin.
FastAPI provides CORSMiddleware for this.
Example:
1
2
3
4
5
6
7
8
9
10
11
12
from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
CORSMiddleware,
allow_origins=[
"http://localhost:5500",
"http://127.0.0.1:5500"
],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
The frontend and backend should use the correct origins.
For example:
1
2
3
4
5
Frontend:
http://localhost:5500

Backend:
http://127.0.0.1:8000
If the browser reports a CORS error, check that the frontend's actual origin is included in the backend configuration.

11. Including Routers

As an application grows, different features can be separated into different routers.
For example:
1
2
3
4
5
6
7
8
9
from fastapi import FastAPI
from app.routers import auth, users, challenges, leaderboard

app = FastAPI()

app.include_router(auth.router)
app.include_router(users.router)
app.include_router(challenges.router)
app.include_router(leaderboard.router)
This keeps the main application file clean.
A larger application could contain:
1
2
3
4
auth.py → Login and registration
users.py → User information
challenges.py → Challenges and game content
leaderboard.py → Scores and rankings

12. Health Check Endpoint

A health endpoint is useful for checking whether the backend is running.
1
2
3
@app.get("/api/health")
async def health():
return {"status": "ok"}
Opening:
1
http://127.0.0.1:8000/api/health
should return:
1
2
3
{
"status": "ok"
}
This is especially useful when monitoring deployed applications.

13. Testing With Swagger UI

One of FastAPI's biggest advantages is automatic API documentation.
After starting the server:
1
uvicorn app.main:app --reload --port 8000
open:
1
http://127.0.0.1:8000/docs
Swagger UI allows developers to:
  • View available endpoints
  • Read request parameters
  • Send test requests
  • View responses
  • Test authentication
  • Debug API behavior
This means you can test many backend APIs without creating a frontend first.

14. Complete Request Flow

Let's look at how a typical application works.
Suppose a user submits a login form.

Step 1: Frontend

The frontend sends:
1
POST /api/auth/login
with the user's credentials.

Step 2: FastAPI

FastAPI receives the request and validates the data.

Step 3: MongoDB

The backend searches the users collection.
1
FastAPI → MongoDB → User Data

Step 4: Authentication

If the credentials are valid, the backend creates an authentication token.

Step 5: Response

FastAPI sends a response to the frontend.
1
2
3
4
{
"access_token": "example-token",
"token_type": "bearer"
}
The frontend can then use the token for protected requests.

15. Common Problems

CORS Error

If you see:
1
Access to fetch ... has been blocked by CORS policy
check:
  • The frontend URL
  • The backend CORS configuration
  • The port number
  • Whether the backend is running
  • Whether the browser is using localhost, 127.0.0.1, or another origin

MongoDB Connection Error

If MongoDB cannot be reached, check:
1
MONGODB_URI
and verify that the database server is running.
For a local MongoDB installation, you might use:
1
mongodb://localhost:27017
For MongoDB Atlas, use the connection string provided by Atlas.

404 Not Found

If an endpoint returns:
1
404 Not Found
check that:
  • The route exists
  • The router is included
  • The HTTP method is correct
  • The URL path is correct
For example:
1
GET /api/users
is different from:
1
POST /api/users

16. Running the Backend

Once everything is configured, start the server:
1
uvicorn app.main:app --reload --port 8000
You should see a message similar to:
1
Application startup complete.
Then test:
1
http://127.0.0.1:8000/api/health
and:
1
http://127.0.0.1:8000/docs

17. How the Components Work Together

The complete architecture can be summarized as:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌─────────────────┐
│ Frontend │
│ HTML / JS / UI │
└────────┬────────┘
│
│ HTTP / JSON
▼
┌─────────────────┐
│ FastAPI │
│ Backend │
└────────┬────────┘
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
Authentication API Routes Validation
│ │
└──────────────┼──────────────┘
│
▼
┌─────────────────┐
│ MongoDB │
│ Database │
└─────────────────┘
Each component has a specific responsibility.
The frontend handles the user interface, FastAPI handles application logic and APIs, and MongoDB stores persistent data.

18. Security Considerations

When building a production application, security should be considered from the beginning.
Important practices include:
  • Never store plain-text passwords.
  • Keep secrets in environment variables.
  • Use HTTPS in production.
  • Validate all user input.
  • Use secure JWT configuration.
  • Restrict CORS origins.
  • Keep dependencies updated.
  • Do not expose database credentials in source code.
  • Use appropriate authentication and authorization.
  • Avoid returning sensitive information through API responses.

Conclusion

FastAPI and MongoDB provide a powerful combination for building modern backend applications.
FastAPI makes it easy to create APIs with automatic documentation and request validation, while MongoDB provides flexible document-based data storage.
The complete development flow is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Create Project
↓
Configure Environment
↓
Connect MongoDB
↓
Create FastAPI Application
↓
Create API Routes
↓
Add Authentication
↓
Configure CORS
↓
Test With Swagger
↓
Deploy
Once these fundamentals are understood, the same architecture can be extended to larger applications such as dashboards, learning platforms, gaming applications, AI applications, and many other web-based systems.
The key idea is simple: the frontend communicates with FastAPI through APIs, FastAPI handles the application logic, and MongoDB stores the application's data.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article