Developing an API for a Mobile Application π
Creating a Backend API for Mobile Apps
In the modern software landscape, mobile applications are often supported by robust backend APIs that manage data, authentication, and other critical functions. In this guide, weβll walk through developing a backend API using FastAPI for a mobile application. FastAPIβs performance and ease of use make it an ideal choice for building scalable and maintainable APIs.
Why FastAPI for Mobile Backend? π
FastAPI is an excellent choice for building backend APIs due to:
- High Performance: FastAPI is one of the fastest frameworks for building APIs in Python.
- Ease of Use: Itβs intuitive and easy to set up, even for complex APIs.
- Automatic Documentation: FastAPI generates interactive API documentation via Swagger UI and ReDoc.
- Type Hints: It uses Python type hints to ensure code quality and reduce bugs.
Prerequisites π
Ensure you have the following installed:
- Python 3.7+
- FastAPI
- Uvicorn (ASGI server)
- SQLAlchemy (for database interactions)
- Alembic (for database migrations)
- Pydantic (for data validation)
Installation π
Install the required dependencies with:
pip install fastapi uvicorn sqlalchemy alembic pydantic
Project Structure π
Hereβs a basic structure for our project:
mobile_backend/
βββ app/
β βββ __init__.py
β βββ main.py
β βββ models.py
β βββ schemas.py
β βββ crud.py
β βββ database.py
β βββ auth.py
β βββ routes.py
β βββ config.py
βββ alembic/
β βββ versions/
β βββ env.py
βββ alembic.ini
βββ .env
βββ requirements.txt
Setting Up the Database π§
1. Configuration File
In app/config.py
, store the configuration settings:
import os
from dotenv import load_dotenv
load_dotenv()
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./test.db")
2. Database Models
In app/models.py
, define the SQLAlchemy models:
from sqlalchemy import Column, Integer, String, Text
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
username = Column(String, unique=True, index=True)
password = Column(String)
class Post(Base):
__tablename__ = "posts"
id = Column(Integer, primary_key=True, index=True)
title = Column(String)
content = Column(Text)
user_id = Column(Integer)
3. Database Connection
In app/database.py
, set up the database connection:
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from .config import DATABASE_URL
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def init_db():
Base.metadata.create_all(bind=engine)
Creating API Endpoints π
1. Schemas
In app/schemas.py
, define the Pydantic schemas:
from pydantic import BaseModel
class UserBase(BaseModel):
username: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
class Config:
orm_mode = True
class PostBase(BaseModel):
title: str
content: str
class PostCreate(PostBase):
pass
class Post(PostBase):
id: int
user_id: int
class Config:
orm_mode = True
2. CRUD Operations
In app/crud.py
, implement CRUD operations:
from sqlalchemy.orm import Session
from . import models, schemas
def get_user(db: Session, user_id: int):
return db.query(models.User).filter(models.User.id == user_id).first()
def create_user(db: Session, user: schemas.UserCreate):
db_user = models.User(**user.dict())
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
def get_post(db: Session, post_id: int):
return db.query(models.Post).filter(models.Post.id == post_id).first()
def create_post(db: Session, post: schemas.PostCreate, user_id: int):
db_post = models.Post(**post.dict(), user_id=user_id)
db.add(db_post)
db.commit()
db.refresh(db_post)
return db_post
3. API Routes
In app/routes.py
, define API routes:
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from . import crud, schemas, database
router = APIRouter()
@router.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(database.SessionLocal)):
return crud.create_user(db=db, user=user)
@router.post("/posts/", response_model=schemas.Post)
def create_post(post: schemas.PostCreate, user_id: int, db: Session = Depends(database.SessionLocal)):
return crud.create_post(db=db, post=post, user_id=user_id)
@router.get("/posts/{post_id}", response_model=schemas.Post)
def read_post(post_id: int, db: Session = Depends(database.SessionLocal)):
db_post = crud.get_post(db, post_id=post_id)
if db_post is None:
raise HTTPException(status_code=404, detail="Post not found")
return db_post
4. Authentication
In app/auth.py
, add basic authentication (you can extend this with OAuth or JWT for more secure implementations):
from fastapi import Depends, HTTPException
from sqlalchemy.orm import Session
from . import crud, schemas, database
def get_current_user(db: Session = Depends(database.SessionLocal), user_id: int = Depends()):
user = crud.get_user(db, user_id=user_id)
if user is None:
raise HTTPException(status_code=404, detail="User not found")
return user
5. Main Application
In app/main.py
, set up the FastAPI application:
from fastapi import FastAPI
from . import routes, database
app = FastAPI()
# Initialize database
database.init_db()
app.include_router(routes.router, prefix="/api/v1")
Database Migrations with Alembic
1. Alembic Configuration
In alembic.ini
, configure Alembic for migrations:
[alembic]
script_location = alembic
sqlalchemy.url = sqlite:///./test.db
[loggers]
keys = root,sqlalchemy,alembic
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = WARN
handlers = console
[logger_sqlalchemy]
level = WARN
handlers = console
qualname = sqlalchemy.engine
[logger_alembic]
level = INFO
handlers = console
qualname = alembic
[handler_console]
class = StreamHandler
args = (sys.stdout,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s] %(message)s
2. Initialize Alembic
Initialize Alembic with:
alembic init alembic
3. Generate Migrations
Create initial migration scripts with:
alembic revision --autogenerate -m "Initial migration"
4. Apply Migrations
Apply migrations to the database:
alembic upgrade head
Running the Application π οΈ
To run the application, use Uvicorn:
uvicorn app.main:app --reload
You can access the interactive API documentation at http://127.0.0.1:8000/docs
Conclusion π
In this guide, weβve built a basic backend API using FastAPI for a mobile application. We covered setting up the project structure, configuring the database, creating models, implementing CRUD operations, defining API routes, and handling basic authentication. FastAPIβs ease of use and high performance make it a powerful tool for building robust backend services.
Stay Connected π
If you enjoyed this guide, feel free to share it and follow my profile for more insights and tutorials!
Thanks for reading and happy coding! π»π