diff --git a/backend/app/main.py b/backend/app/main.py index b3fcf83..c180f37 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -6,6 +6,7 @@ from apscheduler.schedulers.asyncio import AsyncIOScheduler from fastapi import Body, Cookie, FastAPI, HTTPException, Request, Response from fastapi.responses import StreamingResponse from fastapi.middleware.cors import CORSMiddleware +from fastapi.middleware.gzip import GZipMiddleware from fastapi.staticfiles import StaticFiles from . import db, events, search, suggestions, sync @@ -18,6 +19,10 @@ app = FastAPI(title="Netflix Horror DE") scheduler = AsyncIOScheduler() sync_lock = asyncio.Lock() +# Der Katalog ist reines JSON und schrumpft dabei auf etwa ein Fünftel. +# Der Live-Kanal bleibt außen vor: gepufferte Ereignisse kämen zu spät. +app.add_middleware(GZipMiddleware, minimum_size=1024) + app.add_middleware( CORSMiddleware, allow_origins=["http://localhost:5173"], @@ -61,8 +66,19 @@ def status(): } +def katalog_etag(): + """Der Katalog ändert sich nur beim Sync — der Zeitstempel reicht.""" + return f'W/"{db.get_meta("last_sync")}-{db.get_meta("movie_count")}"' + + @app.get("/api/movies") -def movies(): +def movies(request: Request, response: Response): + etag = katalog_etag() + # Unverändert? Dann spart der Browser sich fünf Megabyte. + if request.headers.get("if-none-match") == etag: + return Response(status_code=304, headers={"ETag": etag}) + response.headers["ETag"] = etag + response.headers["Cache-Control"] = "no-cache" return db.all_movies()