Ramverksanalys: Bassystem som ersätter ESI API¶
Bakgrund¶
ESI API är idag byggt på Python Eve (Flask-baserat) och är ett multi-tenant REST API med ~52K rader kod, dynamiska endpoints, ett avancerat rättighetssystem och databasbaserad tenant-isolering. Nästa generation ska vara ett bassystem som:
- Tar bort dynamiska endpoints (custom endpoints/attributes)
- Tar bort multi-system/multi-tenant hantering
- Behåller och förbättrar autentisering (kan slås av/på)
- Behåller och förbättrar rättighetssystem (feature-baserade accessgrupper)
- Fungerar som startpunkt som sedan utvecklas unikt per system
- Potentiellt bli en community-lösning liknande Eve
Nuvarande system: Vad som finns och vad som försvinner¶
Behålls (kärnvärde)¶
| Funktion | Beskrivning |
|---|---|
| JWT-autentisering (ES512) | Token-baserad auth med refresh |
| OAuth2-integrationer | Google, Microsoft, GitHub m.fl. |
| Rättighetssystem (3 lager) | Resurs/metod, attributnivå, datafilter |
| Accessgrupper | Rollbaserade grupper med templates och kluster |
| Organisationshierarki | Consortium → Region → Organization → Department → Unit |
| Cascade-operationer | Delete (deny/null/delete) och update (subscriber-pattern) |
| CRUD med validering | Schemabaserad validering via Cerberus |
| ETag concurrency control | Optimistisk låsning |
| Hooks-system | Pre/post request och databas-hooks |
| Operationslogg (oplog) | Audit trail |
Tas bort¶
| Funktion | Beskrivning |
|---|---|
| Custom endpoints | Dynamisk endpoint-generering via /custom--endpoints |
| Custom attributes | Dynamiska fält under x_{system} namespace |
| Multi-tenant DB-routing | Dynamiskt databasval per system |
| System-registrering | esi-systems collection och API rate limiting per system |
x-{system}-- prefix |
Systemspecifik endpoint-namning |
Omdesignas¶
| Funktion | Nuvarande | Nytt |
|---|---|---|
| Auth toggle | Alltid på, undantag via config-listor | Feature flag: helt av/på |
| Rättigheter | Bundet till organisationshierarki | Feature-baserat, flexibelt |
| Schema-definition | Eve DOMAIN-dict + dynamiska tillägg | Statiska modeller |
Ramverksalternativ¶
1. FastAPI¶
Beskrivning: Modernt Python-ramverk byggt på Starlette (ASGI) med inbyggd Pydantic-validering och automatisk OpenAPI-dokumentation.
Pros¶
| Fördel | Detalj |
|---|---|
| Moderna Python-features | Async/await, type hints, Pydantic v2 — allt som Eve saknar |
| Automatisk API-dokumentation | Swagger UI och ReDoc genereras automatiskt från modeller |
| Pydantic-validering | Kraftfullare och snabbare än Cerberus, med bättre felmeddelanden |
| Dependency Injection | Inbyggt DI-system — perfekt för att bygga pluggbar auth och rättigheter |
| Prestanda | 3-10x snabbare än Flask/Eve tack vare async och Starlette |
| Stort ekosystem | FastAPI-Users, FastAPI-Permissions, SQLModel, Beanie (MongoDB ODM) |
| Aktivt community | 75K+ GitHub stars, snabb utveckling, stor Stack Overflow-bas |
| Enkel att lära | Intuitiv syntax, bra dokumentation, låg inlärningströskel |
| WebSocket-stöd | Inbyggt — möjliggör realtidsfeatures i framtiden |
| Middleware-system | Flexibelt ASGI middleware — enklare att bygga auth/access pipeline |
| Background tasks | Inbyggt stöd utan extern task queue |
| Testning | TestClient baserad på httpx — enklare än Flask test client |
| Community-potential | Mest populära Python API-ramverket — bra bas för open source |
Cons¶
| Nackdel | Detalj |
|---|---|
| Ingen inbyggd CRUD | Eve ger gratis GET/POST/PUT/PATCH/DELETE — med FastAPI skrivs allt manuellt |
| Ingen inbyggd MongoDB-integration | Kräver separat ODM (Beanie, MongoEngine, eller raw PyMongo) |
| Ingen ETag-hantering | Måste implementeras manuellt |
| Ingen oplog | Audit trail måste byggas från grunden |
| Mer boilerplate initialt | Varje endpoint kräver explicit route-definition |
| Async-komplexitet | MongoDB-drivern (Motor) kräver async patterns överallt |
| Migration | Stor omskrivning — inget av Eve-koden återanvänds direkt |
| Cascade-operationer | Måste byggas helt från grunden |
Uppskattad insats för bassystem¶
Hög — Mycket gratis-funktionalitet från Eve försvinner. Men resultatet blir renare och mer underhållbart.
Teknisk stack¶
2. Flask + Egna tillägg (Eve-inspirerat utan Eve)¶
Beskrivning: Bygg bassystemet direkt på Flask, med inspiration från Eve:s arkitektur men utan Eve:s overhead och begränsningar.
Pros¶
| Fördel | Detalj |
|---|---|
| Minimal migration | Befintlig Flask-kunskap och delar av koden kan återanvändas |
| Full kontroll | Ingen Eve-magi — allt är explicit och förutsägbart |
| Moget ekosystem | Flask-JWT-Extended, Flask-Login, Marshmallow, etc. |
| Enkel arkitektur | WSGI, synkront — inga async-utmaningar |
| Pluggbart | Flask blueprints fungerar som moduler — bra för bassystem |
| Befintlig infrastruktur | Gunicorn, cheroot — samma deployment-modell |
| Eve-mönster möjligt | Kan bygga DOMAIN-liknande konfiguration utan Eve:s begränsningar |
Cons¶
| Nackdel | Detalj |
|---|---|
| Synkront | Ingen native async — sämre prestanda under last |
| Ingen automatisk dokumentation | Kräver Flask-RESTX eller flasgger |
| Manuell validering | Marshmallow eller Cerberus — mer arbete än Pydantic |
| Äldre arkitektur | Flask är stabilt men inte modernt — attraherar färre community-bidrag |
| Ingen DI | Flask har inte dependency injection — måste lösas med extensions |
| Begränsat community-intresse | Flask API-ramverk har minskat i popularitet |
Uppskattad insats för bassystem¶
Medium — Kortare väg från nuvarande kod, men resultatet blir mindre modernt.
Teknisk stack¶
3. Django REST Framework (DRF)¶
Beskrivning: Fullständigt REST API-ramverk byggt på Django med inbyggd auth, permissions, serializers och viewsets.
Pros¶
| Fördel | Detalj |
|---|---|
| Mest komplett OOTB | Auth, permissions, throttling, filtering, pagination — allt inbyggt |
| Inbyggt permissions-system | DjangoModelPermissions, DjangoObjectPermissions, custom permission classes |
| Browsable API | Interaktiv API-browser utan extra setup |
| Serializers | Kraftfull validering och transformering — liknande Eve:s schema |
| ViewSets + Routers | Automatisk URL-generering — närmast Eve:s CRUD-generering |
| django-guardian | Objektnivå-permissions — kan ersätta attribut-access |
| Enormt community | Mest mogen Python web community, tusentals packages |
| Admin-panel | Django admin gratis — kan ersätta delar av api-admin |
| Migrationer | Inbyggt schema-migrationssystem |
Cons¶
| Nackdel | Detalj |
|---|---|
| Designad för SQL | Django ORM är SQL-first — MongoDB-stöd är second-class (djongo, django-mongodb) |
| Tungt ramverk | Stor footprint, mycket implicit magi |
| MongoDB-integration fragil | djongo är bristfällig, django-mongodb (MongoDB:s egna) är relativt ny |
| Synkront (huvudsakligen) | Django 4.x har async views men DRF är fortfarande sync |
| Opinionsstarkt | Svårt att avvika från "the Django way" |
| Overkill för API-only | Django har templates, forms, admin — overhead för pure API |
| Community-lösning svår | Django-projekt är svåra att modularisera för plug-and-play |
Uppskattad insats för bassystem¶
Hög — Mest gratis-funktionalitet, men MongoDB-integrationen är en risk.
Teknisk stack¶
4. Litestar (f.d. Starlite)¶
Beskrivning: Modernt ASGI-ramverk med starkt fokus på DI, performance och type safety. Yngre alternativ till FastAPI.
Pros¶
| Fördel | Detalj |
|---|---|
| Bästa DI-systemet | Överlägsen dependency injection — perfekt för pluggbar auth/access |
| Prestanda | Jämförbar eller bättre än FastAPI |
| Guards-system | Inbyggt guard/permission-system — designat för accesskontroll |
| DTO-layer | Dedikerat Data Transfer Object-lager med validering |
| Middleware pipeline | Tydlig, ordnad middleware-kedja |
| OpenAPI | Automatisk dokumentation |
| Type safety | Strängare typing än FastAPI |
Cons¶
| Nackdel | Detalj |
|---|---|
| Litet community | ~5K GitHub stars — svårt att hitta hjälp |
| Mindre ekosystem | Färre tredjepartspaket |
| Instabil API | Fortfarande under aktiv förändring (bröt bakåtkompatibilitet vid namnbytet) |
| MongoDB-stöd | Inget dedikerat stöd — kräver egen integration |
| Risk | Osäkert om projektet överlever långsiktigt |
| Rekrytering | Svårt att hitta utvecklare med erfarenhet |
| Community-bas | För litet för en meningsfull open source-community |
Uppskattad insats för bassystem¶
Hög — Renaste arkitekturen men risken väger tungt.
5. Eve 2.x (förbättrad nuvarande)¶
Beskrivning: Fortsätt med Eve men förenkla radikalt — ta bort dynamiska endpoints, förenkla multi-tenant, modernisera auth.
Pros¶
| Fördel | Detalj |
|---|---|
| Minsta migration | Befintlig kodbas kan refaktoreras istället för omskrivas |
| Beprövat | Eve:s CRUD, ETag, validering, hooks — allt funkar |
| Snabbast till produktion | Veckor istället för månader |
| MongoDB-native | Eve är byggt för MongoDB — ingen impedance mismatch |
| Schema-driven | DOMAIN-dict mönstret är kraftfullt för bassystem |
Cons¶
| Nackdel | Detalj |
|---|---|
| Eve är i princip dött | Senaste release nov 2023, minimal aktivitet, maintainer inaktiv |
| Flask-bundet | Synkront, WSGI — ingen modern async |
| Cerberus begränsningar | Validering saknar Pydantic:s kraft och felhantering |
| Ingen automatisk dokumentation | Kräver manuellt tillägg |
| Community död | Nästan inga nya bidrag — dålig bas för community-projekt |
| Python-version | Eve 2.x stödjer Python 3.8-3.11, osäkert med 3.12+ |
| Technical debt | Att bygga vidare på Eve cementerar beroendet av ett döende ramverk |
| Omöjlig community-lösning | Ingen vill bygga på ett dött ramverk |
Uppskattad insats för bassystem¶
Låg — Men med hög framtida kostnad.
Jämförelsematris¶
| Kriterium | FastAPI | Flask+ | DRF | Litestar | Eve 2.x |
|---|---|---|---|---|---|
| CRUD gratis | - | - | ++ | - | ++ |
| Auth inbyggt | + | + | ++ | + | - |
| Permissions inbyggt | + | - | ++ | ++ | - |
| MongoDB-stöd | ++ (Beanie) | ++ (PyMongo) | - (fragilt) | + | ++ (native) |
| Prestanda | ++ | + | + | ++ | + |
| Community storlek | ++ | ++ | ++ | - | -- |
| Framtidssäkert | ++ | + | ++ | + | -- |
| Dokumentation auto | ++ | - | + | ++ | - |
| DI-system | ++ | - | + | ++ | - |
| Migrationskostnad | Hög | Medium | Hög | Hög | Låg |
| Community-lösning potential | ++ | + | + | - | -- |
| Pluggbar auth | ++ | + | ++ | ++ | - |
| Feature flags | + | + | + | + | - |
Skala: ++ = Utmärkt, + = Bra, - = Svagt, -- = Dåligt
Rekommendation¶
Primärt: FastAPI + Beanie¶
FastAPI är det starkaste alternativet för ett nytt bassystem av följande skäl:
1. Bäst lämpad för "bassystem med pluggbar auth/access"¶
FastAPI:s dependency injection gör det naturligt att bygga auth och rättigheter som moduler som kan slås av/på:
# Auth som kan toggles via config
from base_system.auth import require_auth, optional_auth
from base_system.access import require_permission
@app.get("/users")
async def get_users(
user: User = Depends(require_auth), # Slå av/på via config
_: None = Depends(require_permission("users.read")) # Feature-baserat
):
return await User.find_all().to_list()
# I config:
AUTH_ENABLED = True # False = skippar all auth
2. Feature-baserat rättighetssystem¶
# AccessGroup med features istället för endpoint/metod-matris
class AccessGroup(Document):
name: str
features: list[str] # ["users.read", "users.write", "reports.export"]
class FeatureGuard:
def __init__(self, required_feature: str):
self.feature = required_feature
async def __call__(self, user: User = Depends(get_current_user)):
if self.feature not in user.effective_features:
raise HTTPException(403, "Access denied")
3. Community-potential¶
- FastAPI är det mest populära Python API-ramverket
- Pydantic-modeller är standarden för Python-datavalidering
- Beanie är den ledande async MongoDB ODM
- Utvecklare vill arbeta med FastAPI
4. Vad som behöver byggas¶
| Komponent | Uppskattning | Kommentar |
|---|---|---|
| Basmodeller (User, Org, AccessGroup) | 1-2 veckor | Pydantic/Beanie-modeller |
| CRUD-generering | 1-2 veckor | Generic router factory |
| Auth-modul (JWT + OAuth2) | 1-2 veckor | Delvis porteras från befintlig |
| Rättighetssystem (features) | 2-3 veckor | Nytt design, enklare än nuvarande |
| Cascade-operationer | 1-2 veckor | Beanie events + custom |
| ETag/concurrency | 3-5 dagar | Middleware |
| Oplog/audit | 3-5 dagar | Beanie middleware |
| Hooks-system | 1 vecka | Event-baserat |
| Totalt bassystem | 8-14 veckor |
Sekundärt: Flask (om snabbhet prioriteras)¶
Om målet är att komma till produktion snabbt och med minimal risk, kan Flask med moderna tillägg vara ett pragmatiskt val. Det ger kortast migrationssträcka men saknar FastAPI:s framtidspotential.
Avråder från:¶
- Eve — Dött ramverk, ingen framtid
- DRF — MongoDB-stödet är för fragilt
- Litestar — För litet community, för stor risk
Arkitekturförslag: FastAPI-bassystem¶
esi-base-api/
├── core/ # Kärnmoduler (alltid inkluderade)
│ ├── auth/
│ │ ├── __init__.py # Auth toggle (ENABLED/DISABLED)
│ │ ├── jwt_service.py # JWT encoding/decoding (ES512)
│ │ ├── oauth2/ # OAuth2 providers (pluggbara)
│ │ │ ├── google.py
│ │ │ ├── microsoft.py
│ │ │ └── ...
│ │ ├── dependencies.py # FastAPI Depends() för auth
│ │ └── models.py # Token, Session modeller
│ │
│ ├── access/
│ │ ├── __init__.py # Access control toggle
│ │ ├── features.py # Feature-baserat permissions-system
│ │ ├── guards.py # FastAPI Depends() för access
│ │ ├── groups.py # AccessGroup CRUD och logik
│ │ └── models.py # AccessGroup, Feature modeller
│ │
│ ├── crud/
│ │ ├── __init__.py
│ │ ├── router_factory.py # Genererar CRUD-routes från modell
│ │ ├── etag.py # ETag middleware
│ │ └── pagination.py # Cursor-baserad pagination
│ │
│ ├── cascade/
│ │ ├── delete.py # Cascade delete (deny/null/delete)
│ │ └── update.py # Cascade update (subscriber)
│ │
│ ├── audit/
│ │ ├── oplog.py # Operations-logg
│ │ └── middleware.py # Request/response logging
│ │
│ ├── hooks/
│ │ ├── __init__.py # Hook registration
│ │ ├── lifecycle.py # Pre/post insert/update/delete
│ │ └── events.py # Custom event system
│ │
│ ├── organization/
│ │ ├── models.py # Org, Dept, Unit etc.
│ │ ├── hierarchy.py # Hierarki-logik
│ │ └── routes.py
│ │
│ ├── users/
│ │ ├── models.py
│ │ └── routes.py
│ │
│ └── config.py # Central konfiguration med feature flags
│
├── extensions/ # Valfria tillägg
│ ├── media/ # Filuppladdning (GCS, Azure Blob, S3)
│ ├── email/ # E-postintegration
│ ├── webhooks/ # Utgående webhooks
│ └── gdpr/ # GDPR-verktyg (kryptering, anonymisering)
│
├── templates/ # Mallar för systemspecifika tillägg
│ ├── custom_model.py.template
│ └── custom_route.py.template
│
├── app.py # App factory
├── settings.py # Pydantic Settings
└── pyproject.toml
Feature flag-konfiguration¶
# settings.py
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
# Core toggles
AUTH_ENABLED: bool = True
ACCESS_CONTROL_ENABLED: bool = True
AUDIT_LOG_ENABLED: bool = True
CASCADE_ENABLED: bool = True
ETAG_ENABLED: bool = True
# Auth config
JWT_ALGORITHM: str = "ES512"
JWT_EXPIRY_MINUTES: int = 30
OAUTH2_PROVIDERS: list[str] = ["google", "microsoft"]
# Database
MONGODB_URI: str = "mongodb://localhost:27017"
DATABASE_NAME: str = "my-system"
# Extensions
MEDIA_STORAGE_ENABLED: bool = False
EMAIL_ENABLED: bool = False
WEBHOOKS_ENABLED: bool = False
CRUD Router Factory (Eve-inspirerad)¶
# core/crud/router_factory.py
from fastapi import APIRouter, Depends
from beanie import Document
def create_crud_router(
model: type[Document],
prefix: str,
tags: list[str] = None,
auth: bool = True,
access_feature: str = None,
) -> APIRouter:
"""
Genererar CRUD-routes för en Beanie-modell.
Liknande Eve:s DOMAIN-registrering men explicit.
"""
router = APIRouter(prefix=f"/{prefix}", tags=tags or [prefix])
@router.get("/")
async def list_items(...):
...
@router.get("/{item_id}")
async def get_item(...):
...
@router.post("/", status_code=201)
async def create_item(...):
...
@router.patch("/{item_id}")
async def update_item(...):
...
@router.delete("/{item_id}", status_code=204)
async def delete_item(...):
...
return router
# Användning — liknande Eve DOMAIN:
app.include_router(create_crud_router(User, "users", access_feature="users"))
app.include_router(create_crud_router(Organization, "organizations", access_feature="orgs"))
Sammanfattning¶
| Alternativ | Rekommendation | Motivering |
|---|---|---|
| FastAPI | Starkt rekommenderat | Bästa balansen mellan modernitet, prestanda, community och pluggbarhet. Kräver mest initialt arbete men ger bäst långsiktigt resultat. |
| Flask+ | Acceptabelt | Pragmatiskt val om tid är kritisk. Begränsad framtidspotential. |
| DRF | Avråder | SQL-orienterat, MongoDB-stöd fragilt. |
| Litestar | Avråder | För litet community, för stor risk. |
| Eve 2.x | Starkt avråder | Dött ramverk, ingen framtid som community-lösning. |
Slutsats: FastAPI med Beanie ger det bästa bassystemet — modernt, snabbt, pluggbart och med störst potential att bli en community-lösning. CRUD-generering via router factory ger samma "gratis CRUD" som Eve men med full kontroll och transparens.