Developing an API for a Mobile Application πŸš€

JoΓ«l-Steve N.
4 min readAug 11, 2024

--

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! πŸ’»πŸš€

--

--

JoΓ«l-Steve N.
JoΓ«l-Steve N.

Written by JoΓ«l-Steve N.

Senior Back-End Developer (Python, JavaScript, Java) | Community Manager & Tech Leader

No responses yet