Files
OSIT-AE-API-FastAPI/documentation/archive/REWRITE_PLAN.md

5.1 KiB

Aether API Rewrite Plan

1. Goal

The primary goal of this rewrite is to simplify the Aether API, remove legacy code, and adopt modern FastAPI best practices. This will make the project easier to maintain, extend, and understand.

2. Analysis of the Current State

The current implementation has several key characteristics that contribute to its complexity:

  • "God" Router: A single file, app/routers/api_crud_v2.py, handles all CRUD operations (GET, POST, PATCH, DELETE) for all object types.
  • Dynamic Object Types: The API uses URL path segments (obj_type_l1, obj_type_l2, obj_type_l3) to dynamically determine the object type being operated on.
  • Configuration via Dictionary: The core of the dynamic system is the obj_type_kv_li dictionary in app/ae_obj_types_def.py. This dictionary maps object names to database tables, Pydantic models, and other configuration. This dictionary is inconsistent and contains legacy code.
  • Complex Parameter Handling: Endpoints use a large number of query parameters and headers to control their behavior.
  • Mixed Logic: The code mixes URL parsing, database lookups, data validation, and database operations.

3. Proposed New Structure

To address these challenges, I propose the following new structure:

  • Eliminate the "God" Router: Instead of a single api_crud_v2.py file, create a separate router file for each major object type (e.g., app/routers/sponsorship.py, app/routers/event.py, app/routers/person.py). This aligns with standard FastAPI practice and will make the code much more organized.
  • Explicit Endpoints: Within each router, define explicit endpoints for each operation (e.g., @router.get("/{event_id}"), @router.post("/")). This is more readable, self-documenting (with OpenAPI), and easier to test than the current dynamic URL structure.
  • Dependency Injection for Configuration: Instead of the obj_type_kv_li dictionary, use FastAPI's dependency injection system (Depends) to provide configuration and dependencies to the endpoints. This will make the code more explicit and easier to follow.
  • Centralized Database Logic (CRUD Layer): Create an app/crud/ directory to house all database interaction logic. Each file in this directory would correspond to a specific object type (e.g., app/crud/sponsorship.py, app/crud/event.py). This will separate the API layer from the data access layer, improving separation of concerns.
  • Simplified Models: Review and simplify the Pydantic models. Consolidate the various mdl_, base_name, tbl_, and table_name variations into a more consistent scheme. Use _in and _out models where necessary, but avoid the proliferation of alternate models.
  • Modern Configuration Management: Move away from the mixed config.py and database configuration system. Adopt Pydantic's BaseSettings to load configuration from environment variables or a .env file. This is the standard for modern FastAPI applications and will make the configuration more explicit and easier to manage in different environments.

4. Migration Plan

A big-bang rewrite is risky. I propose a gradual, step-by-step migration:

  1. Step 1: Create the New Structure:

    • Create the app/crud/ directory.
    • Start with a single object type, for example, sponsorship.
    • Create app/routers/sponsorship.py and app/crud/sponsorship.py.
  2. Step 2: Migrate the "Sponsorship" Object Type:

    • In app/crud/sponsorship.py, create functions for get_sponsorship, list_sponsorships, create_sponsorship, update_sponsorship, and delete_sponsorship. These functions will contain the db_sql.py calls.
    • In app/routers/sponsorship.py, create a new APIRouter.
    • Define the explicit endpoints for sponsorship (e.g., @router.get("/sponsorships/{sponsorship_id}")).
    • These endpoints will call the corresponding functions in app/crud/sponsorship.py.
    • Update app/main.py to include the new sponsorship router.
  3. Step 3: Test and Verify:

    • Thoroughly test the new /sponsorships endpoints to ensure they work as expected.
    • You can run the old and new APIs side-by-side to compare results.
  4. Step 4: Repeat for Other Object Types:

    • Repeat the process for each major object type (event, person, order, etc.), one at a time.
  5. Step 5: Preserve and Refactor Core Services:

    • The JWT generation logic in app/routers/api.py should be preserved. Consider moving it to a dedicated app/routers/auth.py router.
    • The jitsi_token endpoint should also be moved to its own router, perhaps app/routers/integrations.py.
  6. Step 6: Deprecate and Remove Legacy Code:

    • Once all object types have been migrated to the new structure, the old app/routers/api_crud_v2.py and app/ae_obj_types_def.py files can be safely deprecated and then removed.
    • The other legacy routers in app/routers/ can also be cleaned up.

This plan provides a structured approach to refactoring your project. By migrating one piece at a time, you can minimize risk and ensure a smooth transition to a more modern and maintainable codebase.