Open gianpaolopascasidc opened 2 years ago
Hey @gianpaolopascasidc :wave: thanks for raising this! I'm going to transfer this over to our API repo for visibility and better assistance 🙂
Any update on this issue? We had to fix it for our projects and actually the fix is (as you can have a pipeline of lambda data sources) :
In function.ts
try {
result = await dataLoader.load(requestTemplateResult.result, {info});
} catch (e) {
In lambda/index.ts
const { fieldName, parentType } = extraData.info;
const batchName = `${this._config.name}.${parentType.name}.${fieldName}`;
Before opening, please confirm:
How did you install the Amplify CLI?
npm (using serverless-appsync-simulator)
If applicable, what version of Node.js are you using?
14.18.3
Amplify CLI Version
amplify-appsync-simulator 2.4.0
What operating system are you using?
MacOS
Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.
Using a local setup to simulate the AWS env
Amplify Categories
function
Amplify Commands
Not applicable
Describe the bug
Premise: on production it's all working good. I have setup a docker machine using serverless offline and serverless-appsync-simulator (a wrapper of amplify-appsync-simualtor). When you invoke a GraphQL query (a pipeline) which triggers different resolvers the simulator will give the following error:
So, as on the production env is all working I have started going around the library code and i located some suspect code (and i tried fixing it and it works). I will explain what problems i found and what solutions i applied. The first problem i discovered is that in
LambaDataLoader
(amplify-appsync-simulator/lib/data-loader/lambda/index.ts) inload(req, extraData)
the extraData is always destructured but in this case the function resolver (amplify-appsync-simulator/lib/resolvers/function.js:40) calls theload(req, extraData)
method omitting the extraData argument. Let's say the solution is usingdataLoader.load(requestTemplateResult.result, { info })
(info is correctly defined in the scope ofresolve()
) instead ofdataLoader.load(requestTemplateResult.result)
. Once you haveinfo
to destructure fromextraData
inLambdaDataLoader.load()
it seems that the functiongetBatchDataResolver()
"caches" a resolver (not yet invoked) using the parentType + queryField as key. The result of this behaviour is that the first defined resolver in the pipeline will be invoked for every function to execute (even if it is defined in another resolver). Finally, i found the solution to solve this assigning the resolver name as cache key. So i changed the line from:const batchName = "${parentType}.${fieldName}";
to:const batchName = this._config.name;
Now, i don't know if it was made on purpose or it is an edge case bug. I really hope this can be a solution and if you think this can work i can open a PR 😄
Expected behavior
All the pipeline is executed invoking the right resolver for every function called.
Reproduction steps
You have to invoke a query using a pipeline with functions from different resolvers.
GraphQL schema(s)
Log output
Additional information
No response