Skip to content

# Basic CRUD

### Use Case 1: Basic FastAPI CRUD API

Scenario: Create a simple user management API with CRUD operations.

Python

    import os
    from fastapi import FastAPI, Depends, HTTPException
    from contextlib import asynccontextmanager
    from pydantic import Field
    from mongo_ops import (
        MongoConnectionManager,
        BaseDocument,
        BaseRepository,
        ModelRegistry,
    )

    # ---------------------------
    # Model Definition
    # ---------------------------
    class User(BaseDocument):
        username: str = Field(..., min_length=3, max_length=50)
        email: str = Field(...)
        is_active: bool = True

    # ---------------------------
    # Repository
    # ---------------------------
    class UserRepository(BaseRepository[User]):
        def __init__(self):
            super().__init__("users", User)

    # Register the model only once
    ModelRegistry.register("users", User, indexes=[("email", 1)])

    # ---------------------------
    # FastAPI Lifespan
    # ---------------------------
    @asynccontextmanager
    async def lifespan(_app: FastAPI):
        """Manage MongoDB connection during the app lifecycle."""
        async with MongoConnectionManager.lifespan(
            uri="mongodb://localhost:27017",
            db_name="mydb"
        ):
            await ModelRegistry.initialize_all()
            yield

    app = FastAPI(lifespan=lifespan)

    # ---------------------------
    # Dependency Injection
    # ---------------------------
    def get_user_repository() -> UserRepository:
        """Dependency-injected repository for users."""
        return UserRepository()

    # ---------------------------
    # Routes
    # ---------------------------
    @app.post("/users/", response_model=User)
    async def create_user(user: User, repo: UserRepository = Depends(get_user_repository)):
        return await repo.create(user)

    @app.get("/users/{user_id}", response_model=User)
    async def get_user(user_id: str, repo: UserRepository = Depends(get_user_repository)):
        user = await repo.get_by_id(user_id)
        if not user:
            raise HTTPException(status_code=404, detail="User not found")
        return user

    @app.get("/users/", response_model=list[User])
    async def list_users(
        skip: int = 0,
        limit: int = 10,
        repo: UserRepository = Depends(get_user_repository),
    ):
        return await repo.get_many(skip=skip, limit=limit)

    @app.put("/users/{user_id}", response_model=User)
    async def update_user(
        user_id: str,
        email: str,
        repo: UserRepository = Depends(get_user_repository),
    ):
        user = await repo.update(user_id, {"email": email})
        if not user:
            raise HTTPException(status_code=404, detail="User not found")
        return user

    @app.delete("/users/{user_id}")
    async def delete_user(
        user_id: str,
        repo: UserRepository = Depends(get_user_repository),
    ):
        deleted = await repo.delete(user_id)
        if not deleted:
            raise HTTPException(status_code=404, detail="User not found")
        return {"message": "User deleted successfully"}