---
Creates FastAPI router with CRUD endpoints for a specified resource.
/plugin marketplace add adelabdelgawad/full-stack/plugin install fastapi-patterns@full-stackIMPORTANT: When this command is invoked, you MUST actually CREATE the files. Do NOT just show the templates.
If not provided, ask the user:
Use the Write tool to create this file at:
{backend}/api/v1/router_{resource}.py
Replace all {Resource} with PascalCase, {resource} with snake_case, and {resources} with plural.
src/backend/api/v1/router_{resource}.py"""
Router for {Resource} management.
"""
from fastapi import APIRouter, Depends, status
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List, Optional
from api.deps import get_session, require_admin
from api.services.{resource}_service import {Resource}Service
from api.schemas.{resource} import (
{Resource}Create,
{Resource}Update,
{Resource}Response,
)
router = APIRouter(prefix="/{resources}", tags=["{resources}"])
@router.post("", response_model={Resource}Response, status_code=status.HTTP_201_CREATED)
async def create_{resource}(
data: {Resource}Create,
session: AsyncSession = Depends(get_session),
_: dict = Depends(require_admin),
):
"""Create a new {resource}."""
service = {Resource}Service()
return await service.create(session, data)
@router.get("/{{{resource}_id}}", response_model={Resource}Response)
async def get_{resource}(
{resource}_id: str,
session: AsyncSession = Depends(get_session),
):
"""Get {resource} by ID."""
service = {Resource}Service()
return await service.get_by_id(session, {resource}_id)
@router.get("", response_model=List[{Resource}Response])
async def list_{resources}(
page: int = 1,
per_page: int = 25,
is_active: Optional[bool] = None,
session: AsyncSession = Depends(get_session),
):
"""List {resources} with pagination."""
service = {Resource}Service()
items, _ = await service.list(session, page=page, per_page=per_page, is_active=is_active)
return items
@router.put("/{{{resource}_id}}", response_model={Resource}Response)
async def update_{resource}(
{resource}_id: str,
data: {Resource}Update,
session: AsyncSession = Depends(get_session),
_: dict = Depends(require_admin),
):
"""Update {resource}."""
service = {Resource}Service()
return await service.update(session, {resource}_id, data)
@router.delete("/{{{resource}_id}}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_{resource}(
{resource}_id: str,
session: AsyncSession = Depends(get_session),
_: dict = Depends(require_admin),
):
"""Delete {resource}."""
service = {Resource}Service()
await service.delete(session, {resource}_id)
src/backend/api/schemas/{resource}.pysrc/backend/api/services/{resource}_service.pysrc/backend/api/repositories/{resource}_repository.pyapp.py:from api.v1.router_{resource} import router as {resource}_router
app.include_router({resource}_router, prefix="/api/v1")
Depends(get_session) for database accessDepends(require_admin) or appropriate auth dependencyAfter creating the router, ADD this import to {backend}/app.py:
from api.v1.router_{resource} import router as {resource}_router
app.include_router({resource}_router, prefix="/api/v1")
After creating the file, output:
✅ Router created: {backend}/api/v1/router_{resource}.py
Don't forget to:
1. Register router in app.py (shown above)
2. Ensure service exists: {backend}/api/services/{resource}_service.py
3. Ensure schemas exist: {backend}/api/schemas/{resource}.py
4. Ensure repository exists: {backend}/api/repositories/{resource}_repository.py
This command MUST:
DO NOT just show the template. ACTUALLY CREATE THE FILE.