parse-server icon indicating copy to clipboard operation
parse-server copied to clipboard

fix: Relation column is always present in the query result regardless of keys/excludeKeys query parameter

Open swittk opened this issue 2 months ago • 4 comments

Pull Request

Issue

Closes: https://github.com/parse-community/parse-server/issues/8500

Approach

This PR addresses issue #8500 where relation fields are never excluded from the returned objects when excludeKeys or specific keys are specified. This is due to the code of both mongoObjectToParseObject and postgresObjectToParseObject internally always spreading the "Relation" keys to the returned object as pointers. The approach taken in this PR is we check if specific keys are specified, and if so, we filter out the Relation fields outside. (A different approach would require passing in those specific keys into mongoObjectToParseObject and postgresObjectToParseObject so they can skip internally too). A minimal edit to GraphQL was necessary too due to previous behaviour not traversing edge.node properly for nested fields, meaning it never addressed nested fields properly, which with this PR would fail. This (hopefully) corrects the behaviour to as intended.

Tasks

  • [x] Add tests

Summary by CodeRabbit

  • Bug Fixes

    • Relation field selection now respects requested keys: only included relations are returned, excluded relations are omitted, and default behavior is preserved.
    • GraphQL field normalization improved to handle nested edge.node paths for accurate projections.
    • Consistent filtering of non-selected relation fields across storage backends for cleaner responses.
  • Tests

    • Added tests validating inclusion, exclusion, and default behavior for relation field selection.

swittk avatar Oct 11 '25 02:10 swittk

🚀 Thanks for opening this pull request!

📝 Walkthrough

Walkthrough

Adds a test for keys/excludeKeys behavior on relation fields. Updates Mongo and Postgres storage adapters to prune relation fields not requested by keys/excludeKeys. Adjusts GraphQL field normalization to strip nested "edges.node" segments. Minor formatting edits in GraphQL utilities and types.

Changes

Cohort / File(s) Summary
Tests: Parse.Query relation keys handling
spec/ParseQuery.spec.js
Adds a test verifying inclusion/exclusion and default behavior of relation fields when using keys and excludeKeys in Parse.Query.
Storage: Mongo adapter relation pruning
src/Adapters/Storage/Mongo/MongoStorageAdapter.js
After mapping Mongo results to Parse objects, when keys are provided, removes Relation fields not present in the requested keys before returning results.
Storage: Postgres adapter relation pruning
src/Adapters/Storage/Postgres/PostgresStorageAdapter.js
Captures a snapshot of requested keys (selectedKeys) and, after converting results to Parse objects, prunes relation fields that are not included in selectedKeys.
GraphQL: query field normalization
src/GraphQL/loaders/parseClassQueries.js
Field normalization in the Find flow now strips both leading edges.node. prefixes and any .edges.node occurrences within field paths to produce correct root keys.
GraphQL: type field selection mapping
src/GraphQL/loaders/parseClassTypes.js
Extends relation field projection logic to strip leading and nested edges.node segments; minor reflow of _User.authDataResponse field formatting.
GraphQL: utils formatting
src/GraphQL/parseGraphQLUtils.js
Minor formatting change in extractKeysAndInclude (no behavioral change).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant API as Parse Server API
  participant Adapter as StorageAdapter (Mongo/Postgres)
  participant DB as Database

  Client->>API: Query (where, keys/excludeKeys)
  API->>Adapter: find(className, query, { keys/excludeKeys })
  Adapter->>DB: Execute DB query
  DB-->>Adapter: Results (raw)
  Adapter->>Adapter: Map DB objects -> Parse objects
  rect rgb(235,245,255)
    note right of Adapter: Post-map filtering (new)
    Adapter->>Adapter: If keys provided, remove Relation fields not in keys\nIf excludeKeys provided, remove excluded Relation fields
  end
  Adapter-->>API: Filtered Parse objects
  API-->>Client: Response
sequenceDiagram
  autonumber
  participant GQL as GraphQL Layer
  participant Loader as parseClassQueries / parseClassTypes
  participant API as Parse Server API

  GQL->>Loader: Selected fields (may include edges.node)
  Loader->>Loader: Normalize fields: strip leading "edges.node." and any ".edges.node" segments
  Loader-->>API: keys/include projection

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • mtrezza

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues Check ✅ Passed The changes implement the core requirement from issue #8500 by filtering out relation fields when specific keys or excludeKeys are provided in both Mongo and Postgres adapters, add corresponding tests to validate this behavior, and include necessary GraphQL adjustments to handle nested edge.node paths.
Out of Scope Changes Check ✅ Passed All functional modifications directly relate to filtering relation fields in storage adapters and supporting GraphQL nested fields as described in the PR objectives, and the only additional change is a harmless formatting update in parseGraphQLUtils.js that does not affect functionality.
Description Check ✅ Passed The pull request description follows the repository template by including the required sections (“Pull Request,” “Issue,” “Approach,” and “Tasks”), correctly links to issue #8500, describes the changes made and lists the completed test task.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Title Check ✅ Passed The title clearly summarizes the main change by stating that relation columns will now respect the keys and excludeKeys parameters and no longer always appear in query results, directly reflecting the core fix implemented in the PR.
✨ Finishing touches
  • [ ] 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment

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 and usage tips.

coderabbitai[bot] avatar Oct 11 '25 02:10 coderabbitai[bot]

:white_check_mark: Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
:white_check_mark: Open Source Security 0 0 0 0 0 issues

:computer: Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

parseplatformorg avatar Oct 11 '25 02:10 parseplatformorg

I will reformat the title to use the proper commit message syntax.