N
Nuxtā€¢5mo ago
Felix

How to keep state in SSR requests?

Hey, I am validating a session token by hitting a DB. I see it is hitting the DB once for every SSR request (e.g. useAsyncData.) How can I avoid the DB hit per SSR request?
26 Replies
Felix
FelixOPā€¢5mo ago
So I have a 00.auth.ts middleware in server/middleware. It seems this middleware runs for every SSR request. My understanding that since it's server rendered all the state of the original request should be available. But the middleware runs repeatedly and the event object is a new object so I cannot cache state on it either
manniL
manniLā€¢5mo ago
cache the result in your API endpoint might be the easiest
Felix
FelixOPā€¢5mo ago
by what key?
manniL
manniLā€¢5mo ago
the session token itself? šŸ¤”
Felix
FelixOPā€¢5mo ago
right i see... just store it in memory somewhere to fake the db lookup? assuming that it will soon get evicted because the lambda dies? what i don't understand is it's just a function call; the context is already on the stack somehwere. is it not possible to somehow access this?
manniL
manniLā€¢5mo ago
well you can save it e.g. in a kv store in-mem is tricky with serverless
the context is already on the stack somehwere. is it not possible to somehow access this?
No, it is recreated per call šŸ™‚
Felix
FelixOPā€¢5mo ago
Oh why is that
manniL
manniLā€¢5mo ago
Various reasons, e.g. that you don't want cross state pollution šŸ™‚
Felix
FelixOPā€¢5mo ago
What is cross state pollution?
manniL
manniLā€¢5mo ago
state of user a is "accidentally" part of state of user b and with serverless or edge, you can't have a "consistently" shared context anyway (same with any multi instance deployment) you can still use plugins to make sure that each requests has a certain object/class/... available though
Felix
FelixOPā€¢5mo ago
But if initial request binds to user a then for that request context how could it ever be user b?
manniL
manniLā€¢5mo ago
oh wait maybe we are misunderstanding here šŸ™‚ I am talking about multiple initial requests
Felix
FelixOPā€¢5mo ago
I really don't get it. So request flies in, route is matched, handler runs, some $fetch calls happen and since we are on the server a FN runs instead of a http req. In that FN all the context should be available no? Right. I'm taking about a single initial request. I made sure no other xhr requests show in the network tab. But event.context is always cleared and I don't know how I can access the initial request context
manniL
manniLā€¢5mo ago
you could get the event via useRequestEvent()
Felix
FelixOPā€¢5mo ago
What I am seeing is that for every $fetch the entire server/Middleware runs again on a fresh event object. Wouldn't getRequestEvent just return that?
manniL
manniLā€¢5mo ago
no, this is correct. it is treated the same way when doing an "external" request to that endpoint
Felix
FelixOPā€¢5mo ago
Which brings me back to why and how
manniL
manniLā€¢5mo ago
Alexander Lichter
YouTube
Nuxt vs. Nitro - What does what in your App
šŸ¤šŸ» Nuxt and Nitro go hand in hand - but sometimes so well that the borders between both blur for developers. Wouldn't it be helpful to understand why Pinia composables can't be used in the server folder and when exactly Nitro comes into play? Fear no more - all of that and more will be covered in this video! Key points: šŸ‘€ When Nitro is used in ...
manniL
manniLā€¢5mo ago
think of nitro as standalone api server which also renders your nuxt app but these are distinct tasks
Felix
FelixOPā€¢5mo ago
Sorry if I come across rude but I don't understand how sth so simple can be made to be so difficult it can't be explained in one sentence . Kind of baffling. I'm surprised I also couldn't find answers on google. I love working with Nuxt overall. This is the first hol'on a minute moment. I'll give the video a watch tonight.
manniL
manniLā€¢5mo ago
I'm happy to try again. Could you maybe reword the question? When you do calls "on the client side" of your app to an API endpoint, then it is simply not different than when calling them via postman or just putting the URL in the browser (except you might pass headers and similar to them) Commonly you authenticate your user with the session ID, send the ID to the API and your backend will check validity. This is the case for any kind of stateless API
Felix
FelixOPā€¢5mo ago
Yup but $fetch short-circuits and runs the code immediately on the server during the initial request. No client involved For SSR pages
manniL
manniLā€¢5mo ago
that's correct, on the server it does! There, $fetch calls are not actually happening but are emulated because you can just run the event handler's code šŸ‘ But not on the client side, as you said
Felix
FelixOPā€¢5mo ago
Yes... So on the server why can't I get access to state established in the initial request object I noticed that when I do a $fetch from my middleware/01.auth.global.ts middleware, the initial event context is retained! That is what I want. But why is this not happening for $fetch requests issued in page components is what I am trying to figure out. I cloned nuxt and will start digging... ok. so idk if this is a bug in nuxt or not. but check this out:
const x = useAsyncData(
() => {
// this will NOT retain context in SSR call:
const fetch = $fetch;

// this retains context in SSR call:
// const fetch = useRequestFetch();

return fetch("/api/user");
},
{
immediate: true,
server: true,
watch: false,
},
);
const x = useAsyncData(
() => {
// this will NOT retain context in SSR call:
const fetch = $fetch;

// this retains context in SSR call:
// const fetch = useRequestFetch();

return fetch("/api/user");
},
{
immediate: true,
server: true,
watch: false,
},
);
Felix
FelixOPā€¢5mo ago
Felix
FelixOPā€¢5mo ago
and filed a bug. we'll see what comes of it.. https://github.com/nuxt/nuxt/issues/27909
GitHub
SSR Context Lost Ā· Issue #27909 Ā· nuxt/nuxt
Environment Operating System: Darwin Node Version: v21.6.2 Nuxt Version: 3.12.2 CLI Version: 3.12.0 Nitro Version: 2.9.7 Package Manager: [email protected] Builder: - User Config: ssr, devtools Runtime Mo...
Want results from more Discord servers?
Add your server