Ez a tananyag elágazása. Nem mondom meg, melyiket válaszd — végigvezetem a hét szempontot, ami tényleg dönt, megmutatom azt az egy műszaki tényezőt, ami Cloudflare-en gyakran eldönti a kérdést, és megadom a hibrid határvonalát, ami a legvalószínűbb válasz. A végén egy konkrét checklist, amit a saját helyzetedre kitöltesz.
| Szempont | Full-stack Nuxt mellett szól | Külön API mellett szól |
|---|---|---|
| Kliensek | Csak webes felület, esetleg egy-két integráció | Mobilapp, partner-API, több frontend — ezeknek úgyis kell egy stabil, verziózott API |
| Migrációs kockázat | Zöldmezős rész, vagy vállalható a nagyobb átírás | Nagy, működő Express-kódbázis, amit nem akarsz egyszerre mozgatni |
| Csapat | Egy csapat viszi a frontendet és a backendet | Külön backend-csapat, saját release-ciklussal |
| Latency | Az adat is Cloudflare-en van (D1/R2/KV), vagy Hyperdrive-on át közel | Az API és az adatbázis egy régióban marad — lásd a 9.3-at, ez a legfontosabb |
| Típusok, sebesség | Végponttól a komponensig egy típuslánc, nincs duplikált szerződés | OpenAPI-generált kliens is működik, csak lassabb a kör |
| Üzemeltetés, költség | Egy deploy, egy log-forrás, egy skálázási modell | Marad a megszokott üzemeltetés, nem kell két platformot tanulni |
| Ami nem fut Workers-en | Nincs nehéz számítás, natív lib, vagy hosszú futású munka | Van: PDF-generálás natív libbel, nagy batch, ML-inferencia, órákig futó job |
Ez a modul legfontosabb szakasza, és pont az a szempont, ami az általános „Nuxt full-stack vagy nem” vitákban nem szokott szerepelni, mert csak edge-hostingnál él.
Az SSR értelme az, hogy a szerver gyorsan össze tudja rakni a HTML-t. Ehhez adatot kér le. Ha a Worker az edge-en fut — mondjuk a felhasználóhoz közel, Budapesten —, de az API az AWS eu-central-1-ben, akkor minden egyes SSR-lekérés kimegy Frankfurtba és vissza.
Négy válasz létezik erre, és mind a négy legitim:
| Válasz | Mit csinál | Mikor jó |
|---|---|---|
| Összevonás | Egy BFF-végpont, ami egyetlen kéréssel elhozza, amit az oldal igényel — N round trip helyett egy | Szinte mindig. Ez az első lépés, olcsó és sokat hoz. |
| Smart Placement | A Cloudflare a Workert nem a felhasználóhoz, hanem az origin közelébe helyezi | Ha az SSR sokat beszélget egy távoli backenddel. Egy konfigsor. |
| Adat közelebb | Hyperdrive az Aurora elé (kapcsolat-pooling + query cache), vagy olvasási replika | Ha a Postgres marad, de a kapcsolatfelépítés a szűk keresztmetszet |
| Kevesebb SSR-adat | A személyre szabott rész server: false-szal a kliensre kerül (5. modul) |
Ha a lassú lekérés nem is kell az első festéshez |
A legtöbb csapat ide köt ki. Nem kompromisszum, hanem tudatos felosztás: ami a felhasználóhoz közel értékes, az menjen a Nitróba; ami nehéz vagy nem edge-barát, maradjon kint.
| Tedd a Nitróba | Hagyd kint (vagy más eszközben) |
|---|---|
|
Session és auth (cookie-kezelés, tenant-feloldás) Az SSR-hez kellő adat összevonása Publikus, cache-elhető végpontok Webhook-fogadás (gyors 200 + sorba tétel) Feltöltési URL kiadása, R2-műveletek Minden új végpont, ha nincs okod máshova tenni |
Nagy batch-feldolgozás, éjszakai zárás PDF/Excel generálás natív könyvtárral ML-inferencia, képfeldolgozás sharp-palPercekig futó tranzakciók Ami a meglévő API-ban jól működik és nincs okod hozzányúlni |
server/api/[...].ts, ami mindent továbbtol az Express-nek, a legrosszabb mindkét világból: megkapod a plusz hálózati ugrást, de nem kapsz cserébe semmit — se összevonást, se típusokat, se hibafordítást. Ha csak proxyzol, akkor hívd az API-t közvetlenül a böngészőből, és spórold meg a Workert.// server/utils/upstream.ts — egy helyen kezelt kimenő hívás
export function upstream(event: H3Event) {
const cfg = useRuntimeConfig(event)
return $fetch.create({
baseURL: cfg.apiBaseUrl,
timeout: 5000,
onRequest({ options }) {
// ✗ SOHA ne told tovább a felhasználó cookie-ját
// ✓ a szerver a saját, rövid életű szolgáltatás-tokenjével hív
options.headers.set('authorization', `Bearer ${serviceToken(cfg)}`)
options.headers.set('x-tenant-id', event.context.tenant.id)
options.headers.set('x-request-id', event.context.requestId)
},
onResponseError({ response }) {
// a belső hibaformátumot fordítsuk a sajátunkra (5. modul)
throw createError({
statusCode: response.status === 401 ? 403 : response.status,
statusMessage: response._data?.message ?? 'Upstream hiba',
})
},
})
}
// server/api/dashboard.get.ts — ÖSSZEVONÁS: 1 kérés a böngészőnek, párhuzamos upstream
export default defineEventHandler(async (event) => {
await requireSession(event)
const api = upstream(event)
const [projects, usage, notices] = await Promise.all([
api('/projects?limit=10'),
api('/usage/current'),
api('/notices'),
])
// és itt formázzuk a DTO-t — a belső séma nem szivárog ki (5. modul)
return { projects: projects.map(toProjectDto), usage: toUsageDto(usage), notices }
})
event-et (8. modul). Ez tartja nyitva az ajtót visszafelé is./api/v1/-ként indulni, mint később törni.A biztonságos út a strangler-minta: nem cserélsz, hanem körbenősz.
Válaszolj őszintén; a jelölés mutatja, merre húz a válasz.
Mert az SSR-hez adat kell, és minden lekérés oda-vissza utat jelent az edge és a távoli API között. Egy régiós szerver az API mellett van, tehát a lekérései gyorsak; az edge Workernek viszont a felhasználó van közel, az adat nem. Három soros lekérés × egy nagy RTT = jelentős TTFB-növekmény. Válaszok: összevonás, Smart Placement, Hyperdrive, vagy kevesebb SSR-adat.
Megkapod a plusz hálózati ugrás összes költségét, de semmit nem kapsz cserébe: se összevonást, se típusokat, se hibafordítást, se cache-t. Ha a BFF-ed csak továbbtol, akkor a böngésző hívja közvetlenül az API-t, és nem kell a Worker a láncba.
Mert ezzel a felhasználói hitelesítő adat átkerül egy másik bizalmi zónába, és minden ottani hiba vagy naplózás kiteszi. A helyes minta: a BFF ellenőrzi a session-t, majd a saját, rövid életű szolgáltatás-tokenjével hív, és a felhasználó/tenant azonosítóját külön fejlécben adja át — így az upstream oldalon egyértelmű, hogy szolgáltatás hívja, kinek a nevében.
Az egyszerre nyitható 6 kimenő kapcsolat és a kérésenkénti subrequest-korlát. Mindkettő a kevesebb, nagyobb hívás felé terel — vagyis az összevonás felé, ami amúgy is a BFF fő értéke.
A session- és auth-réteget (cookie-kezelés, tenant-feloldás), az SSR-hez való adatösszevonást, a publikus cache-elhető végpontokat, a webhook-fogadást és a feltöltési URL-ek kiadását. Ezek mind olyanok, amiknek a felhasználóhoz közel van értelme, és amiket a 10. modulban meg is csinálunk.
Mert ott már megkapod a fő hasznokat — új funkciók egy helyen készülnek, közös típusok, gyorsabb SSR —, miközben a működő, nehéz részek maradnak ott, ahol jól működnek. A „mindent egy helyre” nem önmagában érték; a kevesebb mozgó alkatrész az, és azt a 2. fázis nagyrészt megadja.