T
TanStack2mo ago
afraid-scarlet

Is there a way to set a global server context?

I'd like to have some objects passed in to every request handlers (e.g. createFileRoute, createServerFn) (kind of like a server context, NOT a request context). Some of these objects would be: - a database connection (created via createServerOnlyFn) - a parsed env object containing environment variables and other settings - objects representing a connection to other services
25 Replies
afraid-scarlet
afraid-scarletOP2mo ago
Something like dependency injection
variable-lime
variable-lime2mo ago
why not a request context?
afraid-scarlet
afraid-scarletOP2mo ago
It's not something that needs to be initialized per request. It's something that should be initialized per server instantiation
variable-lime
variable-lime2mo ago
server instantiation is not something that start is aware of it totally depends on the actual runtime it could be instantiated per request (some PaaS like cloudflare) or long lived nodejs instances so you could just initialize at module scope maybe and reference this?
afraid-scarlet
afraid-scarletOP2mo ago
It's unclear to me how module scoped variables behave when creating client/server bundles. Since I can't have a server only declaration for a db connection pool for example, is that gonna leak to the client ?
variable-lime
variable-lime2mo ago
why cant you have that server only declaration?
afraid-scarlet
afraid-scarletOP2mo ago
For a module scoped variable? As far as I know that's not supported. Only functions, no? Via createServerOnlyFn?
variable-lime
variable-lime2mo ago
const x = createServerOnlyFn(() => init())()
afraid-scarlet
afraid-scarletOP2mo ago
Yeah but then if this module is indirectly imported in client code wouldn't that x be also initialized?
variable-lime
variable-lime2mo ago
it would, yes
afraid-scarlet
afraid-scarletOP2mo ago
And that's a problem, no?
variable-lime
variable-lime2mo ago
the problem is importing this in client code and createServerOnlyFn will prevent you from doing that a different way is to do all of that initialization in a custom server.ts entry point
afraid-scarlet
afraid-scarletOP2mo ago
const db = whatever; Then you declare a server function that uses that. Then you declare a queryOptions that references the server function. You use queryOptions in client code.
variable-lime
variable-lime2mo ago
and then put the result into the fetch context
afraid-scarlet
afraid-scarletOP2mo ago
Wouldn't that scenario break? ^ I've done custom server.ts before. It's not pretty. I know it's the ultimate escape hatch but if there's another way I'd rather take that
variable-lime
variable-lime2mo ago
not pretty?
afraid-scarlet
afraid-scarletOP2mo ago
Seems like I'm missing something because this looks like a very basic use case (using a db and a server function)
variable-lime
variable-lime2mo ago
Server Entry Point | TanStack Start React Docs
Server Entry Point [!NOTE] The server entry point is optional out of the box. If not provided, TanStack Start will automatically handle the server entry point for you using the below as a default. Thi...
afraid-scarlet
afraid-scarletOP2mo ago
Then I don't understand what you are suggesting because the custom server thing I've tried involves that yes but also either express or fastify (not shown there) and it's just absolutely a PITA to maintain and make work both in dev mode and production
afraid-scarlet
afraid-scarletOP2mo ago
It's not clear what that means. Is there an example somewhere?
variable-lime
variable-lime2mo ago
apart from the docs, no you can pass anything as a request context and it will then end up as context in middleware, server functions
afraid-scarlet
afraid-scarletOP2mo ago
You mean those two paragraphs? Or is there an example I'm missing? I get that. I don't understand where I can hold the "global" value though. Because fetch is run per request, no?
variable-lime
variable-lime2mo ago
yes but if you init in server.ts at module scope, it will only run once (assuming your runtime lives across multiple requests)
afraid-scarlet
afraid-scarletOP2mo ago
Am I overreacting though? What's the normal recommended way to have something like a db handle?

Did you find this page helpful?