Current User Items Cache
- I have a page in my solid start project called /contracts
- My goal is to get the current users contracts on this page
- My original solutions was like this in the contracts.tsx page:
const contracts = query(() => {
"use server";
// call /api route
// api route has middle wear that populates userId on event.locals
// api route gets the current users contracts
// return current users contracts
}, "contracts");
But then i saw this in the docs: https://docs.solidjs.com/solid-start/reference/server/use-server
const getUser = query((id) => {
"use server";
return db.getUser(id);
}, "users");
- And now I'm wondering, w/ my current implementation, is the server going to cache contracts for multiple users under the same "contracts" key?
- If so what's the best practice way to solve this please? I would prefer not to send an id to query b/c that seems less secure
- Unless I send an id like the example: query((id))
- And then also verify the id on the server maybe?
Thanks!
"use server" - SolidDocs
Documentation for SolidJS, the signals-powered UI framework
9 Replies
is the server going to cache contracts for multiple users under the same "contracts" key?-
query
is entirely a client side construct. The section under "use server"
represents an RPC call to the server.
- the "contracts"
key is relevant to the client side router, making it possible for code to target a particular query
for revalidationrevalidate - SolidDocs
Documentation for SolidJS, the signals-powered UI framework
The server doesn't cache anything, however you need to be mindful of request isolation. Any application specific data that is request specific lives under
eventRequest.locals
— do not use JS modules that rely on module globals to cache values because JS modules are shared between concurrent requests within the same server worker (SolidStart has two workers; one for SSR the other for RPC).
The one you have to watch out for is module global context values that are loaded with account specific data during SSR.
https://github.com/peerreynders/solid-start-sse-chat/blob/d2b9070f956947c940dc2046abbbbf4bbcbd58e2/src/components/history-context/index.tsx#L372
https://github.com/peerreynders/solid-start-sse-chat/blob/d2b9070f956947c940dc2046abbbbf4bbcbd58e2/src/app-store.tsGitHub
solid-start-sse-chat/src/app-store.ts at d2b9070f956947c940dc2046ab...
Basic Chat demonstration with server-sent events (SSE) - peerreynders/solid-start-sse-chat
GitHub
solid-start-sse-chat/src/components/history-context/index.tsx at d2...
Basic Chat demonstration with server-sent events (SSE) - peerreynders/solid-start-sse-chat
If so what's the best practice way to solve this please? I would prefer not to send an id to query b/c that seems less secureYou're using
https
right?
If anybody has the means to “decipher” the id
they would also have the means to decipher the payload coming back—which is probably worse.thanks @peerreynders ! I love your wisdom! So my goal is to:
const contracts = query(() => {
"use server";
// call /api route
// return current users contracts
}, "contracts");
So each user in each browser will have their own cache for their personal contracts, which is perfect!
Oor I misunderstood & it does not work that way! lol
1. Why call an API route? Those are typically created so that the client can access the data without RPC. Now if you are also supporting non-SolidStart clients then the API route makes sense. But if it's just for SolidStart clients and you are using
"use server"
already, just get it done right then and there. (Right now you can't use the Nitro's $fetch
in SolidStart to save the extra http hop).Fetch - Nitro
Nitro provides a built-in fetch API that can be used to get data from server endpoints or from other sources. It's built on top of the unjs/ofetch.
2. Don't think of
query
as a cache. Its purpose is to de-duplicate requests. As long as at least as one createAsync()
is actively using the query
the response payload is reused—indefinitely.
As soon a the reference count to a query
payload drops to zero it's considered invalid. Only when a query
is initially loaded via a route preload
there is a 5 second grace period during which the payload is considered valid until the first createAsync
uses it.
Also any plain action
will implicitly revalidate all query
s—if you only want to target specific query
payloads you can do so with the revalidate
option on reload
or json
(an empty array will opt out of revalidations).
The idea is that the client needs to understand the nature of the data it is using:
- If you are actively using data through query
via createAsync()
you must know it's “fresh”.
- However actions
are used to mutate remote data—so unless specifically configured, all active query
payloads are considered potentially stale and will start fetching (only preload
ed query
s are eligible for single-flight, others will issue separate fetches).
- If there are other circumstances where you may want to re-fresh the query
s use revalidate.action - SolidDocs
Documentation for SolidJS, the signals-powered UI framework
reload - SolidDocs
Documentation for SolidJS, the signals-powered UI framework
json - SolidDocs
Documentation for SolidJS, the signals-powered UI framework
Really appreciate how thorough your responses are! Teaching me a lot thank you! Especially super valuable knowing how the references work w/ query thank you!
My backend could be used for other devices in the future (mobile applications) and I am working w/ a guy that loves testing routes w/ postman so I would love to stay boring w/ api routes so just a fetch w/in query() is perfect for me, I created a script to generate types & a function so i can get typesafety to the api though!

I would love to stay boring w/ api routes so just a fetch w/in query() is perfect for me, I created a script to generate types & a function so i can get typesafety to the api though!.Ok, I must be missing something; then just
fetch
from the query
and ignore "use server"
.