fix: Apply requestContextMiddleware on directAccess requests#10603
fix: Apply requestContextMiddleware on directAccess requests#10603Moumouls wants to merge 7 commits into
Conversation
Nested SDK ops under directAccess bypass Express, so DI injected via requestContextMiddleware was missing on Cloud hooks. Re-apply the middleware after Config.get() in ParseServerRESTController.
|
🚀 Thanks for opening this pull request! We appreciate your effort in improving the project. Please let us know once your pull request is ready for review. Tip
Note Please respond to review comments from AI agents just like you would to comments from a human reviewer. Let the reviewer resolve their own comments, unless they have reviewed and accepted your commit, or agreed with your explanation for why the feedback was incorrect. Caution Pull requests must be written using an AI agent with human supervision. Pull requests written entirely by a human will likely be rejected, because of lower code quality, higher review effort and the higher risk of introducing bugs. Please note that AI review comments on this pull request alone do not satisfy this requirement. Our CI and AI review are safeguards, not development tools. If many issues are flagged, rethink your development approach. Invest more effort in planning and design rather than using review cycles to fix low-quality code. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough
ChangesDirect-access request context
Estimated code review effort: 4 (Complex) | ~45 minutes Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant ParentSave
participant ParseServerRESTController
participant requestContextMiddleware
participant ChildBeforeSave
ParentSave->>ParseServerRESTController: route nested Child.save
ParseServerRESTController->>requestContextMiddleware: apply request context
requestContextMiddleware-->>ParseServerRESTController: set req.config.aCustomController
ParseServerRESTController->>ChildBeforeSave: execute trigger with request config
ChildBeforeSave-->>ParentSave: observe aCustomController
🚥 Pre-merge checks | ✅ 6 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (6 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/ParseServerRESTController.js`:
- Around line 32-63: Update applyRequestContextMiddleware and its documentation
to define a minimal synthetic-request contract for requestContextMiddleware,
explicitly stating that Express-only request properties and methods such as
req.get(), req.header(), req.ip, and req.body are unavailable. Ensure the
middleware is expected to use only the supported fields on the synthetic req,
rather than adding partial Express compatibility.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 65797509-2cd9-4814-aaf3-ad36e5001eb4
📒 Files selected for processing (4)
spec/rest.spec.jssrc/Options/Definitions.jssrc/Options/docs.jssrc/ParseServerRESTController.js
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## alpha #10603 +/- ##
==========================================
- Coverage 93.55% 93.54% -0.01%
==========================================
Files 192 192
Lines 16832 16846 +14
Branches 248 248
==========================================
+ Hits 15747 15759 +12
- Misses 1064 1066 +2
Partials 21 21 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Clarify that directAccess uses a minimal synthetic request and that Express-only accessors are unavailable, addressing review feedback.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/Options/index.js`:
- Around line 421-422: Update the requestContextMiddleware type declaration in
the Options definitions to allow both synchronous and Promise-based completion
by using a void-or-Promise<void> return type, while preserving the existing
request, response, and next parameter types.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 53f020c2-d9f8-4ca2-bc23-29f358fdebcb
📒 Files selected for processing (4)
src/Options/Definitions.jssrc/Options/docs.jssrc/Options/index.jssrc/ParseServerRESTController.js
🚧 Files skipped from review as they are similar to previous changes (1)
- src/ParseServerRESTController.js
Align with handleRequest style while keeping callback and Promise middleware settlement support.
Align the Flow type with runtime support for async DI middleware.
|
@coderabbitai full review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/ParseServerRESTController.js`:
- Around line 55-80: Update the requestContextMiddleware contract in
applyRequestContextMiddleware to explicitly require settlement via next() or a
resolving/rejecting Promise. Document that the synthetic req.config.req.headers
are only DI support and res is a bare object, so middleware must not rely on
response termination or other implicit paths.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: c10f6058-2a17-4445-b362-cc31ea0c2ef6
📒 Files selected for processing (5)
spec/rest.spec.jssrc/Options/Definitions.jssrc/Options/docs.jssrc/Options/index.jssrc/ParseServerRESTController.js
Document that directAccess synthetic res is bare and middleware must settle via next() or a Promise to avoid hanging nested ops.
| if (result != null && typeof result.then === 'function') { | ||
| result.then(() => done(), done); | ||
| } | ||
| }); |
There was a problem hiding this comment.
@coderabbitai can we do
import { promisify } from 'node:util';
await promisify(config.requestContextMiddleware)(req, {});is it equivalent and supported in our target runtimes
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- package engine/runtime declarations ---'
rg -n -C 3 '"engines"|"node"\s*:|Node\.js|Node.js|node versions|supported.*node|supported.*Node' \
package.json .nvmrc .node-version README.md CONTRIBUTING.md 2>/dev/null || true
printf '%s\n' '--- package metadata excerpts ---'
sed -n '1,180p' package.json 2>/dev/null || true
printf '%s\n' '--- node: imports and promisify usages ---'
rg -n -C 2 "from ['\"]node:|require\(['\"]node:|\\bpromisify\\s*\\(" \
-g '*.js' -g '*.mjs' -g '*.cjs' -g 'package.json' .
printf '%s\n' '--- CI Node-version matrices ---'
fd -HI '(^|/)(.*\.(yml|yaml)|Dockerfile.*|\.nvmrc|\.node-version)$' . \
--exclude node_modules --exclude .git \
| xargs -r rg -n -i -C 2 'node-version|node-version-file|node:|NODE_VERSION|nvm|setup-node' || trueLength of output: 26765
@dblythy, yes—the import is supported by our target runtimes. package.json requires Node 20.19+, 22.13+, or 24.11+, all of which support node:util, and the repository already uses both util.promisify and node: core-module imports.
But it is not fully equivalent to the current adapter:
await promisify(config.requestContextMiddleware)(req, {});This works for callback middleware that invokes next() / next(err). promisify appends its error-first callback as the third argument, so the call shape is correct.
It does not settle from a returned Promise, though. Thus this valid async middleware would hang:
async req => {
req.config.aCustomController = controller;
}The current implementation intentionally supports both callback and Promise styles, including hybrid middleware with first-settlement-wins behavior. So we can simplify to promisify only if the documented contract is narrowed to callback-style middleware; otherwise, the existing adapter is needed.
Pull Request
Issue
Closes: #10602
Related: #8480 (requestContextMiddleware), orthogonal to #10291 (context clone).
Approach
With
directAccess: true, nested SDK ops useParseServerRESTControllerandConfig.get()without going through Express, sorequestContextMiddlewarenever ran and DI onreq.configwas lost.After loading a fresh config via
Config.get(), re-applyrequestContextMiddlewareon a synthetic{ config, headers: {} }request (callback + Promise). Skip when a parent config is already passed (batch children).Tasks
Test plan
rest context→ nested directAccess DI (was red before fix)rest context→ existing HTTP DI still passesParseServerRESTControllersuite (22 specs)Summary by CodeRabbit
requestContextMiddlewarevalues are correctly available in nested direct-access flows.requestContextMiddlewarebehavior for internal direct-access requests, including the limited synthetic request and which Express-style accessors aren’t available.