HoudiniGraphql / houdini

The disappearing GraphQL framework
http://www.houdinigraphql.com
MIT License
895 stars 95 forks source link

@UserId value get's forwarded to backend as grapqhl variable #1007

Closed AlecAivazis closed 1 year ago

AlecAivazis commented 1 year ago

Discussed in https://github.com/HoudiniGraphql/houdini/discussions/1006

Originally posted by **olmo-hake** March 20, 2023 Once i start to use @list in combination with @parentId i get into trouble. The $userID value is forwarded to my backend as a graphql variable and my backend is unable to handle the request, because of the unknown variable. Am i missing something? ```gql query load_folder($filter: FolderFilter!) { core { folder(where: $filter) { id name folders @list(name:"Subfolders"){ id name } files { name extension mimetype size url } } } } mutation add_folder($folder:Folder!, $folderID:ID!){ core{ insert_folder_one(object:$folder){ ...Subfolders_insert @parentID(value: $folderID) } } } ```
AlecAivazis commented 1 year ago

Hey @olmo-hake!

Sorry to hear you're running into this! Would you be able to push up a reproduction somewhere I can take a look? I tried to reproduce it in our test suite but the variables were being correctly removed from the mutation 🤔

ghost commented 1 year ago

Hi @AlecAivazis,

thanks for the quick response! I quite busy at the moment and tbh not sure how to quickly reproduce the problem. Can you test with out a corresponding graphql endpoint based on the sveltekit project alone? Will work around it for now via manuall array updates and come back to it as soon as i have a bit more time and a better idea how to reproduce it.

AlecAivazis commented 1 year ago

Okay no problem. I'll go ahead and close this issue. Feel free to open another one when you have some time to dig into what could be happening 👍

ChrisSG commented 1 year ago

@AlecAivazis I think you were refering to this: https://github.com/HoudiniGraphql/houdini/blob/3b43098c20dd6fa95c8fb1b8f52568832e2033ee/packages/houdini/src/codegen/generators/artifacts/tests/artifacts.test.ts#L319

But it seems that the parentID is still in the Input section. What OP is trying to say is that the variables are forwarded to the grqphql backend which then complains that it is handed variables which are not actually being used inside the query...

UPDATE:

I did execute the tests and the variables are successfully removed. Seems the document forwarded to the server is different, or there is a different reason like additional parameters in the query which prevent correct removal etc.

AlecAivazis commented 1 year ago

Huh so your seeing a situation where the artifact's raw value isn't what is sent to the API?

ChrisSG commented 1 year ago

Not exactly. But I see that the variable I use in the Mutation are being sent to the server. The directive @parentID has been removed. With the variable still present the server rejects the Mutation stating there are "unexpected variables"...

ChrisSG commented 1 year ago

Ok, so I put my schema and my docs into your test suite and ran 'variables only used by internal directives are scrubbed'. The result is that the variables are successfully removed from my the resulting raw. They are still in the resulting "input". I guess the error must be somewhere else. Maybe not sending the sanitized doc over to the server?!

image

ChrisSG commented 1 year ago

I worte a Plugin to resolve this in the meantime...

const SanitaizeVariablesOnlyUsedByDirectivesPlugin: ClientPlugin = () => {
    return {
        // remove all variables from ctx.stuff.inputs.marshaled objects which are not in the ctx.text
        // this is needed because the HoudiniClient will send all variables to the server
        // even if they are not used in the query
        beforeNetwork(ctx, { next }) {
            if (ctx.stuff?.inputs?.marshaled) {
                ctx.stuff.inputs.marshaled = Object.keys(ctx.stuff.inputs.marshaled).reduce((acc, key) => {
                    if (ctx.text.includes(key)) {
                        acc[key] = ctx.stuff.inputs.marshaled[key];
                    }
                    return acc;
                }, {});
            }

            // move onto the next step in the pipeline
            next(ctx);
        },
        // restore the  ctx.stuff.inputs.marshaled objects from ctx.variables
        afterNetwork(ctx, { resolve }) {
            if (ctx.stuff?.inputs?.marshaled && ctx.variables) {
                ctx.stuff.inputs.marshaled = structuredClone(ctx.variables);
            }
            // move onto the next step in the pipeline
            resolve(ctx);
        }
    };
};
ChrisSG commented 1 year ago

@AlecAivazis Is this about right? Any side effects to consider?

xmlking commented 2 months ago

@AlecAivazis . I am also facing this issue. userId should not be send to our GQL backend. can you please help with this.

const deletePersonalAccessToken = graphql(`
    mutation DeletePersonalAccessToken($id: uuid!, $userId: ID!) {
      deleteAuthRefreshToken(id: $id) {
        ...Personal_Access_Tokens_remove @parentID(value: $userId)
      }
    }
  `);
image