refactoring-backend #3
@@ -768,7 +768,67 @@ APScheduler 4.x (async mode) manages recurring background tasks.
|
||||
|
||||
---
|
||||
|
||||
## 9.2 Deployment Constraints
|
||||
## 9.2 nginx Routing Rules
|
||||
|
||||
The reverse proxy (nginx) must route requests correctly to prevent frontend SPA fallback rules from hiding backend 404 errors. The following location blocks ensure proper behavior:
|
||||
|
||||
### Location Block Priority
|
||||
|
||||
nginx uses **longest-prefix matching** to determine which location block handles a request:
|
||||
1. Exact matches (`location =`) — highest priority
|
||||
2. Regular expression matches (`location ~`) — second priority
|
||||
3. Prefix matches (`location /prefix`) — matched in order of specificity (longest first)
|
||||
4. Catch-all (`location /`) — lowest priority
|
||||
|
||||
### Routing Configuration
|
||||
|
||||
| Location Block | Rule | Purpose |
|
||||
|---|---|---|
|
||||
| `location /api/` | `proxy_pass http://backend:8000;` — **no `try_files`** | Proxy all API requests to FastAPI backend. Any unmatched API route (typos, invalid paths) returns 404 from the backend. |
|
||||
| `location /assets/` | `try_files $uri =404;` | Serve static assets with long-term caching. Return 404 if file doesn't exist. |
|
||||
| `location /` | `try_files $uri $uri/ /index.html;` | SPA fallback: serve `index.html` for all unmatched routes (client-side routing). |
|
||||
|
||||
### Routing Behavior
|
||||
|
||||
```
|
||||
Request → /api/some-endpoint
|
||||
↓
|
||||
nginx matches location /api/ (longest prefix)
|
||||
↓
|
||||
proxy_pass → backend:8000
|
||||
↓
|
||||
Backend returns 404 if endpoint doesn't exist (✓ correct)
|
||||
Client sees 404, not SPA HTML
|
||||
|
||||
Request → /some-page
|
||||
↓
|
||||
nginx matches location / (catch-all)
|
||||
↓
|
||||
try_files looks for file, then directory, then /index.html
|
||||
↓
|
||||
Serves /index.html (React Router handles client-side routing)
|
||||
↓
|
||||
Client sees 200 with HTML (✓ correct for SPA)
|
||||
|
||||
Request → /api/typos
|
||||
↓
|
||||
nginx matches location /api/ (longest prefix, NOT catch-all)
|
||||
↓
|
||||
proxy_pass → backend:8000
|
||||
↓
|
||||
FastAPI returns 404 (✓ correct, not caught by SPA fallback)
|
||||
```
|
||||
|
||||
### Critical Implementation Notes
|
||||
|
||||
- **Never add `try_files` to the `/api/` location block** — this would hide backend 404s.
|
||||
- **The `/api/` location must come before the `/` catch-all** in the config (this is automatically respected via longest-prefix matching).
|
||||
- **No inherited `try_files` rules** — the `/api/` location has no global `try_files` that could affect it.
|
||||
- **Backend 404 responses pass through nginx unchanged** — nginx does not rewrite 404 responses from the backend.
|
||||
|
||||
---
|
||||
|
||||
## 9.3 Deployment Constraints
|
||||
|
||||
### Single-Worker Requirement
|
||||
|
||||
|
||||
Reference in New Issue
Block a user