Replies: 2 comments 3 replies
-
+1 dealing with a similar problem |
Beta Was this translation helpful? Give feedback.
-
I'm trying to achieve something very similar. A request ID is read from the headers and I want to attach it to all log entries in the context of that request. In other projects using apollo-server I could simply set up a child logger in the context callback and directly access it from individual resolvers. Using pino one approach would be using a mixin in the global logger: export const logger = pino({
mixin: () => ({ request_id: headers().get('x-request-id') })
}); However this must be synchronous and doesn't work with the new async export const logger = pino({
hooks: {
async logMethod(args, method) {
return method.apply(this.child({ request_id: (await headers()).get('x-request-id') }), args);
},
},
}); While this seems to work, async hooks are not actually supported so this might have undesired side effects or stop working eventually. I understand that middleware is the wrong place for this since it runs in its own environment (and possibly even distributed on separate hosts) but there are plenty of use cases for a shared per-request context:
I've seen others use react's cache, however that is only recommended in server components, not for other server code like API endpoints. Being quite new to nextjs I might be biased by my experience with other frameworks, so let me know how you would approach my issue! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
I need access to data that is specific to a request in a few different places (all server-side) in a next.js app -- for example, the Host header or a request ID. For now, my team has been using the headers function and other request-specific state management functions from next.js.
This has worked OK so far. However, with next.js 15 those functions (headers, cookies, etc) have become async, and I have a few non-async functions that currently call them and must remain non-async (because they're passed as callbacks to synchronous third-party APIs).
This could easily be solved by first calling eg. headers on an async context (eg. middleware), then storing the result somewhere globally accessible for the lifetime of the request, but I'm failing to find a way to do that on next.js.
One solution I've tried is using Node.js' AsyncLocalStorage: start a context when the middleware starts running, and end it when the middleware ends... except since next.js 12 middleware don't look much like middleware anymore, and AFAIK there's no way you can wait for your route's response. On this same vein, I also though about decorating every single route with a call to AsyncLocalStorage.run but that's clearly not ideal.
I've also thought about simply using global variables, but I guess that wouldn't work unless next.js serialized and ran each request synchronously or if it spawned a new entire application for every request, both of which aren't true.
A third similar option would be to have a global
Map<RequestId, State>
, but as there doesn't seem to be a way to define code in a single place to safely and reliably execute logic right before a response is sent in next.js (ahem middleware), that map could grow indefinitely with each request, as I wouldn't be able to reliably remove entries from the map as each request finished.Additional information
No response
Example
No response
Beta Was this translation helpful? Give feedback.
All reactions