Skip to content

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

FastAPI + Pydantic v2 + Beanie (MongoDB ODM) + Motor (async MongoDB)
+ PyJWT + Authlib + uvicorn

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

Flask + Marshmallow + PyMongo + Flask-JWT-Extended + Flask-RESTX

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

Django + DRF + django-mongodb/djongo + django-guardian + dj-rest-auth

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.