-
Notifications
You must be signed in to change notification settings - Fork 553
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
MiddlewareStacks added to commands in lib-dynamodb never get applied. #3095
Comments
Hi @c0pp3rt0p, thanks for opening this issue. After looking into this, I found that the problem is caused because when the QueryCommand instance that you have created, which implementation is defined in lib-dynamodb package, create a new instance of the QueryCommand, but of the implementation that is defined in client-dynamodb package, and this new instance is used as the final command to be executed, but just the inputs you provided are given to this new command instance. This means that the middleware stack from the first command instance is ignored. I will mark this issue to be reviewed so we can address this further. Here is the code that I used to reproduce: import {DynamoDBDocumentClient, QueryCommand} from "@aws-sdk/lib-dynamodb";
import {DynamoDBClient} from "@aws-sdk/client-dynamodb";
const client = DynamoDBDocumentClient.from(new DynamoDBClient({
region: 'REGION',
}));
const queryCommandParams = {
TableName: "test-table",
KeyConditionExpression: "id = :id",
ExpressionAttributeValues: {
':id': 'id',
},
};
const queryCommand = new QueryCommand(queryCommandParams);
queryCommand.middlewareStack.add((next) => async (args) => {
console.log('We should see this output!');
// result.response contains data returned from next middleware.
return await next(args);
},
{
step: 'build',
name: 'addFooMetadataMiddleware',
tags: ['METADATA', 'FOO'],
}
);
const response = await client.send(queryCommand);
console.log('Response: ', response);
/**
* Suggestion:
* Since middlewareStack is a readonly variable, we can not override the middlewareStack of the new command instance
* with the middlewareStack of the first command instance created. We could maybe create an array in
* QueryCommand of lib-dynamodb package, which will hold all the middleware functions provided, and then we
* just need to add those functions to the middlewareStack of the final command to be executed. For example:
*
* New function:
* public addToMiddlewareStack(middleware) {
* this.middlewareStackItems.push(middleware);
* }
*
* And in the resolveMiddleware function:
* const { marshallOptions, unmarshallOptions } = configuration.translateConfig || {};
* const command = new __QueryCommand(marshallInput(this.input, this.inputKeyNodes, marshallOptions));
*
* for (let item of this.middlewareStackItems) {
* command.middlewareStack.add(item);
* }
* const handler = command.resolveMiddleware(clientStack, configuration, options);
*
* And how to use it:
* const queryCommand = new QueryCommand(queryCommandParams);
* queryCommand.addToMiddlewareStack((next) => async (args) => {
* console.log('We should see this output!');
* // result.response contains data returned from next middleware.
* return await next(args);
* },
* {
* step: 'build',
* name: 'addFooMetadataMiddleware',
* tags: ['METADATA', 'FOO'],
* }
* );
*
*/ Thanks! |
@c0pp3rt0p As workaround, you could add the middleware to the client instead. Please see my code below: import {DynamoDBDocumentClient, QueryCommand} from "@aws-sdk/lib-dynamodb";
import {DynamoDBClient} from "@aws-sdk/client-dynamodb";
const client = DynamoDBDocumentClient.from(new DynamoDBClient({
region: 'us-east-2',
}));
client.middlewareStack.add((next) => async (args) => {
console.log('We should see this output!');
// result.response contains data returned from next middleware.
return await next(args);
},
{
step: 'build',
name: 'addFooMetadataMiddleware',
tags: ['METADATA', 'FOO'],
}
);
const queryCommandParams = {
TableName: "test-table",
KeyConditionExpression: "id = :id",
ExpressionAttributeValues: {
':id': 'id',
},
};
const queryCommand = new QueryCommand(queryCommandParams);
const response = await client.send(queryCommand);
console.log('Response: ', response); Here is the output: We should see this output!
Response: {
'$metadata': {
httpStatusCode: 200,
requestId: 'REQUEST-ID',
extendedRequestId: undefined,
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
}; |
This release contains a fix that should make command middlewareStacks useable: https://github.com/aws/aws-sdk-js-v3/releases/tag/v3.141.0 It applies to this package: https://www.npmjs.com/package/@aws-sdk/lib-dynamodb/v/3.141.0 |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread. |
Describe the bug
Commands in lib-dynamodb do not add their
middelwareStack
to the underlying command.Adding any middleware stack to a command in the lib-dynamodb package has no effect.
Your environment
NodeJs/TS on mac
SDK version number
@aws-sdk/package-name@3.43.0
Is the issue in the browser/Node.js/ReactNative?
no
Details of the browser/Node.js/ReactNative version
$ node -v
v14.17.0
Steps to reproduce
Please share code or minimal repo, and steps to reproduce the behavior.
Observed behavior
The expected console output "You will never see this", is never shown.
Expected behavior
when the command is sent "You will never see this" should be output to the console.
Additional context
It appears the commands in lib-dynamodb are missing the step to concat the current middleware with the newly constructed command. Only the client middlewares get resolved. See comments in the code below.
link to relevant code:
aws-sdk-js-v3/lib/lib-dynamodb/src/commands/QueryCommand.ts
Line 83 in e35f78c
The text was updated successfully, but these errors were encountered: