Which strategy best prevents state leakage in shared context objects across asynchronous hook chains?
0 reputation · 30 Sept 2020, 02:51 UTC
0 reputation · 30 Sept 2020, 02:51 UTC
FeathersJS utilizes a hooks system to manage the request/response lifecycle, where a shared context object is passed through a sequential pipeline. This allows before and after hooks to share state and modify data before it reaches the service handler or the client.
When implementing complex, asynchronous business logic within these chains, there is a risk of unintended state mutation or data leakage if multiple hooks modify the same context properties. While the pipeline is sequential, the reliance on a mutable object for state management can lead to unpredictable behavior in high-concurrency environments or deeply nested hook structures.
What is the recommended pattern for isolating temporary state within the context object to ensure that after hooks only process intended transformations? Does FeathersJS provide a native mechanism to freeze or scope specific context properties to prevent accidental overrides by subsequent hooks in the chain?
35275 reputation · 30 Sept 2020, 13:45 UTC
The recommended pattern to isolate temporary state in the FeathersJS context object across asynchronous hook chains is to store that state in a Symbol‑keyed property (e.g., context[Symbol.for('myapp/hook-temp')] = value).
context.context object; treating it as mutable only for documented fields (params, data, result) is the safest baseline.const HOOK_TEMP = Symbol.for('myapp/hook-temp');
before hook (or any hook that needs to set temporary data):
async function setTemp(context) {
context[HOOK_TEMP] = { userId: context.params.user.id, requestId: context.id };
return context;
}
after hook, read (and optionally clean up) the temporary value:
async function useTemp(context) {
const temp = context[HOOK_TEMP];
// … use temp for logging, enrichment, etc.
delete context[HOOK_TEMP]; // optional, prevents reuse
return context;
}
Does your project already enforce a Symbol‑based naming convention for hook‑scoped state? If not, establishing one is required before applying the pattern above.
Create a test before hook that sets context[HOOK_TEMP] and an after hook that reads it; run the service under load (e.g., with autocannon) and confirm that the Symbol value does not appear in unrelated requests.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.