Skip to content

fix: Apply requestContextMiddleware on directAccess requests#10603

Open
Moumouls wants to merge 7 commits into
parse-community:alphafrom
Moumouls:fix/request-context-middleware-direct-access
Open

fix: Apply requestContextMiddleware on directAccess requests#10603
Moumouls wants to merge 7 commits into
parse-community:alphafrom
Moumouls:fix/request-context-middleware-direct-access

Conversation

@Moumouls

@Moumouls Moumouls commented Jul 23, 2026

Copy link
Copy Markdown
Member

Pull Request

Issue

Closes: #10602

Related: #8480 (requestContextMiddleware), orthogonal to #10291 (context clone).

Approach

With directAccess: true, nested SDK ops use ParseServerRESTController and Config.get() without going through Express, so requestContextMiddleware never ran and DI on req.config was lost.

After loading a fresh config via Config.get(), re-apply requestContextMiddleware on a synthetic { config, headers: {} } request (callback + Promise). Skip when a parent config is already passed (batch children).

Tasks

  • Add tests
  • Add changes to documentation (option help text)
  • Add security check
  • Add new Parse Error codes to Parse JS SDK

Test plan

  • rest context → nested directAccess DI (was red before fix)
  • rest context → existing HTTP DI still passes
  • ParseServerRESTController suite (22 specs)

Summary by CodeRabbit

  • Bug Fixes
    • Improved reliability for nested REST/Cloud Code operations so request-scoped requestContextMiddleware values are correctly available in nested direct-access flows.
    • Enhanced REST batch execution with async/await, optional transactional batching, and more consistent retry/abort behavior.
    • Preserved prior fallback when a request can’t be routed by the main router.
    • Requests with invalid request context now fail fast with a clear validation error.
  • Documentation
    • Clarified requestContextMiddleware behavior for internal direct-access requests, including the limited synthetic request and which Express-style accessors aren’t available.
  • Tests
    • Added coverage for nested direct-access dependency injection behavior.

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.
@parse-github-assistant

Copy link
Copy Markdown

🚀 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

  • Keep pull requests small. Large PRs will be rejected. Break complex features into smaller, incremental PRs.
  • Use Test Driven Development. Write failing tests before implementing functionality. Ensure tests pass.
  • Group code into logical blocks. Add a short comment before each block to explain its purpose.
  • We offer conceptual guidance. Coding is up to you. PRs must be merge-ready for human review.
  • Our review focuses on concept, not quality. PRs with code issues will be rejected. Use an AI agent.
  • Human review time is precious. Avoid review ping-pong. Inspect and test your AI-generated code.

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.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

ParseServerRESTController now applies request context middleware during direct-access handling, uses async/await for batch and request routing, preserves transaction and fallback behavior, and adds regression coverage for configuration propagation into nested Cloud Code triggers.

Changes

Direct-access request context

Layer / File(s) Summary
Synthetic request middleware application
src/ParseServerRESTController.js, src/Options/*
Loads configuration when needed and applies callback- or Promise-based requestContextMiddleware with single-settlement protection. Documentation describes the synthetic request shape and unavailable Express accessors.
Request routing and batch execution
src/ParseServerRESTController.js
Refactors batch and main request handling to async/await while retaining transactions, retries, context cloning, status metadata, authentication, and REST fallback behavior.
Nested-operation regression coverage
spec/rest.spec.js
Tests that middleware-injected configuration is visible in a nested Child beforeSave triggered by saving a Parent with direct access enabled.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers: dblythy, mtrezza

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
Loading
🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The controller refactor also changes async routing, batch execution, and context cloning, which are beyond the DI fix. Move the batch and structuredClone refactor into a separate PR and keep this one focused on reapplying requestContextMiddleware for directAccess.
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title uses the required fix: prefix and clearly describes the directAccess requestContextMiddleware fix.
Description check ✅ Passed The description follows the template with Issue, Approach, Tasks, and Test plan sections filled in.
Linked Issues check ✅ Passed The PR re-applies requestContextMiddleware on synthetic directAccess requests and adds a regression test for nested DI.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Security Check ✅ Passed No new vuln patterns: the patch only reapplies server-side middleware and deep-clones context; no eval, file, auth-bypass, or trust-boundary widening.
Engage In Review Feedback ✅ Passed The PR now documents the synthetic-request contract and bridges requestContextMiddleware callback/Promise settlement explicitly, addressing the review note.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Moumouls

This comment has been minimized.

@Moumouls
Moumouls requested a review from mtrezza July 23, 2026 13:17

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5838c07 and cd56c63.

📒 Files selected for processing (4)
  • spec/rest.spec.js
  • src/Options/Definitions.js
  • src/Options/docs.js
  • src/ParseServerRESTController.js

Comment thread src/ParseServerRESTController.js
@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.63265% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.54%. Comparing base (5838c07) to head (da446a8).

Files with missing lines Patch % Lines
src/ParseServerRESTController.js 81.63% 9 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Clarify that directAccess uses a minimal synthetic request and that
Express-only accessors are unavailable, addressing review feedback.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between e45b7f7 and 624f49f.

📒 Files selected for processing (4)
  • src/Options/Definitions.js
  • src/Options/docs.js
  • src/Options/index.js
  • src/ParseServerRESTController.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/ParseServerRESTController.js

Comment thread src/Options/index.js Outdated
Align with handleRequest style while keeping callback and Promise
middleware settlement support.
Comment thread src/ParseServerRESTController.js
Align the Flow type with runtime support for async DI middleware.
@Moumouls

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5838c07 and 343023a.

📒 Files selected for processing (5)
  • spec/rest.spec.js
  • src/Options/Definitions.js
  • src/Options/docs.js
  • src/Options/index.js
  • src/ParseServerRESTController.js

Comment thread src/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);
}
});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai can we do

import { promisify } from 'node:util';

await promisify(config.requestContextMiddleware)(req, {});

is it equivalent and supported in our target runtimes

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 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' || true

Length 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.

@mtrezza mtrezza left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unresolved conversations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

requestContextMiddleware DI missing on nested directAccess ops

3 participants