Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make new function exposed from the enricher so lookaheads can check and evaluate skips / includes #177

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

trkohler
Copy link
Contributor

@trkohler trkohler commented Aug 25, 2022

Bug description

Even though fields inside the entities() field of a collection are @skip-ed as part of a query, they still make the calls to backends as if they are not skipped but just discards the data instead of returning it to the client.

Expected behavior

Backend systems should not be called in the case that the field it is required for is skipped.

Current behavior

Backends are called even if the field is skipped

src/execution.ts Outdated Show resolved Hide resolved
src/variables.ts Outdated Show resolved Hide resolved
@trkohler trkohler changed the title draft [wip] propagate skip / include information to the enricher function so lookaheads would know it in runtime [wip] Sep 6, 2022
package.json Outdated Show resolved Hide resolved
@trkohler trkohler changed the title propagate skip / include information to the enricher function so lookaheads would know it in runtime [wip] make new function exposed from the enricher so lookaheads can check and evaluate skips / includes [wip] Sep 13, 2022
@trkohler trkohler marked this pull request as ready for review September 15, 2022 10:30
src/resolve-info.ts Outdated Show resolved Hide resolved
src/resolve-info.ts Outdated Show resolved Hide resolved
@trkohler trkohler changed the title make new function exposed from the enricher so lookaheads can check and evaluate skips / includes [wip] make new function exposed from the enricher so lookaheads can check and evaluate skips / includes Sep 30, 2022
@trkohler trkohler force-pushed the add-directives-to-enricher branch 2 times, most recently from 84315f3 to d24cbdc Compare October 4, 2022 11:40
@trkohler
Copy link
Contributor Author

trkohler commented Jan 31, 2023

current problem

this test with snapshot is not passing src/__tests__/resolve-info.test.ts:902

there is query

query {
          node(id: "root") {
            id
            ... on Image {
              width
            }
            ... on DocumentElement {
              __typename
              ... on Image {
                url
                tags {
                  name
                }
              }
              ... on Media {
                tags {
                  id
                }
              }
            }
          }
        }

and I receive that my result contains property name but apparently it should not

"tags": Object {
            "Tag": Object {
              "id": Object {
                Symbol(LeafFieldSymbol): true,
              },
    -         "name": Object {
    -           Symbol(LeafFieldSymbol): true,
    -         },

but we query property name on tags, aren't we? why we shouldn't have this property in snapshot?

UPD: test is correct. my debug document (access only for zalandoers)

@oporkka
Copy link
Member

oporkka commented Feb 19, 2023

and I receive that my result contains property name but apparently it should not

"tags": Object {
            "Tag": Object {
              "id": Object {
                Symbol(LeafFieldSymbol): true,
              },
    -         "name": Object {
    -           Symbol(LeafFieldSymbol): true,
    -         },

but we query property name on tags, aren't we? why we shouldn't have this property in snapshot?

I re-read the comment now, and realised it is other way around. The snapshot is expecting name to be there, but the result returned by infNode.fieldExpansion does not have it. Would that mean that the PR caused some sort of regression which the tests are now catching?

@trkohler
Copy link
Contributor Author

trkohler commented Feb 20, 2023

yes, that's why it certainly must not be merged and I need to find a place where it's happening because my additions were not meant to modify query response tree.

Comment on lines 253 to 258
const fieldExpansion: FieldExpansion = Object.create(
{
__shouldInclude: shouldInclude
},
{}
);
Copy link
Contributor

Choose a reason for hiding this comment

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

I have 0 ideas how, but these lines break objects merging and lead to the failing test in this PR.

Copy link
Member

Choose a reason for hiding this comment

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

The object merging breaks because we set here a prototype for the object, but lodash mergeWith is expecting objects to be plain objects to function, and it does not know how to merge objects that have non null prototypes.

See https://lodash.com/docs/4.17.15#merge

Array and plain object properties are merged recursively. Other objects and value types are overridden by assignment.

Basically because we are not having plain objects anymore, in this code https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/.internal/baseMergeDeep.js#L69-L89 we skip this merge part, and just override the value, as stated above

Copy link
Member

Choose a reason for hiding this comment

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

Our customizer for mergeWith is only customizing the leaf nodes, and returns undefined for other nodes, i.e. then normal lodash merge is used.

One way to deal with this would be to extend the customizer function to also merge our new objects that have prototype

mergeWith(obj, src, (objValue, srcValue): LeafField | undefined => {
if (isLeafField(objValue)) {
if (isLeafField(srcValue)) {
return {
...objValue,
...srcValue
};
}
return objValue;
} else if (isLeafField(srcValue)) {
return srcValue;
}
return undefined;
});

};
function createLeafField<T extends object>(
props: T,
shouldInclude: (variables: ShouldIncludeVariables) => boolean
Copy link
Member

Choose a reason for hiding this comment

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

The typename "ShouldIncludeVariables" should be ShouldIncludeParams. Otherwise it would read variables.variables[variableName].

Copy link
Contributor Author

Choose a reason for hiding this comment

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

renamed.

}
};

type RootFieldExpansion = {
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need this separate type?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

initially it was because root doesn't have ShouldIncludeExtension since root is always included.

@boopathi
Copy link
Member

Update: The fix to the above issue will have conflicts with this PR. So, I suggest that we hold this PR until we fix the bug in #166 - the fix to #166 would likely remove the __internalShouldInclude which this PR relies on.

Troy Kohler added 5 commits April 11, 2023 13:35
…st suite and remove the skip from the describe block. Also, fix the schema object formatting.

test(resolve-info.test.ts): add tests for resolver info and field expansion
…ed twice instead of once when skipping a field
@trkohler trkohler closed this Apr 13, 2023
@trkohler trkohler reopened this Apr 13, 2023
Troy Kohler added 2 commits April 13, 2023 16:21
… based on __shouldInclude() result

test(resolve-info.test.ts): add tests for not skipping expensive function based on __shouldInclude() result

refactor(resolve-info.ts): simplify createLeafField function using object spread syntax
feat(resolve-info.ts): add support for nested __internalShouldIncludePath in expandFieldNode function
@trkohler
Copy link
Contributor Author

trkohler commented Apr 13, 2023

current todo / problems

  • exposing function in new attribute would be reflected in snapshots. need to figure out this
  • tests are very simple now... can be much better [need ideas of test cases. would appreciate suggestions]
  • address comments
  • coverage increase (???)
    408,443 src/resolve-info.ts

Troy Kohler added 8 commits April 13, 2023 16:53
…eParams

refactor(resolve-info): rename shouldInclude function parameter from variables to params
refactor(resolve-info): remove empty object from createLeafField function call
refactor(resolve-info): remove empty object from Object.create call in expandFieldNode function
… of ShouldIncludeExtension

refactor(resolve-info.ts): use Object.create and Object.assign to create LeafField object
refactor(resolve-info.ts): use Object.defineProperties to define __shouldInclude property in FieldExpansion object
refactor(resolve-info): simplify rightKey variable assignment
fix(resolve-info): add missing semicolons and fix eslint errors
…h tags excluded and tag query with name field
….test.ts

refactor(resolve-info): simplify expandFieldNode function in resolve-info.ts
test(resolve-info.test.ts): clear mock before each test
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.

None yet

4 participants