Last active
November 12, 2023 01:48
-
-
Save busticated/c90f099c9b5a12c9111ce1d34afed466 to your computer and use it in GitHub Desktop.
How to use ARC's / AWS' `client._doc.transactWrite()` method?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Trying to implement field uniqueness as described in: | |
// https://aws.amazon.com/blogs/database/simulating-amazon-dynamodb-unique-constraints-using-transactions/ | |
// Using: | |
// mocha: v10.2.0 | |
// node: v18.18.2 | |
// macOS: Sonoma v14.1 (23B74) | |
import sinon from 'sinon'; // sinon@17.0.1 | |
import { expect } from 'chai'; // chai@4.3.10 | |
import sandbox from '@architect/sandbox'; // @architect/sandbox@5.9.2 | |
import arc from '@architect/functions'; // @architect/functions@7.0.0 | |
describe('DynamoDB: UnknownOperationException: UnknownError', () => { | |
let tables; // b/c describe() doesn't support `async` callbacks :( | |
before(async () => { | |
await sandbox.start({ quiet: true }); | |
tables = await arc.tables(); | |
}); | |
afterEach(() => { | |
sinon.restore(); | |
}); | |
after(async () => { | |
await sandbox.end(); | |
}); | |
describe('Using `.transactWrite()`', () => { | |
it('Starts with empty db', async () => { | |
const records = await tables.chocotaco.scan({}); | |
expect(records.Count).to.equal(0); | |
expect(records.Items).to.eql([]); | |
expect(records['$metadata'].httpStatusCode).to.equal(200); | |
}); | |
it('Creates new record', async () => { | |
const client = await arc.tables(); | |
const TableName = 'chocotaco'; | |
await client._doc.transactWrite({ | |
TransactItems: [ | |
{ | |
Put: { | |
TableName, | |
ConditionExpression: 'attribute_not_exists(pk)', | |
Item: { | |
pk: 'my-fake-pk', | |
sk: 'my-fake-sk', | |
username: 'fake-username', | |
email: 'fake@example.com' | |
} | |
} | |
}, | |
{ | |
Put: { | |
TableName, | |
ConditionExpression: 'attribute_not_exists(pk)', | |
Item: { | |
pk: 'unique-username:fake-username', | |
sk: 'unique-username' | |
} | |
} | |
}, | |
{ | |
Put: { | |
TableName, | |
ConditionExpression: 'attribute_not_exists(pk)', | |
Item: { | |
pk: 'unique-email:fake@example.com', | |
sk: 'unique-email' | |
} | |
} | |
} | |
] | |
}); | |
}); | |
}); | |
it('Delete record', async () => { | |
const client = await arc.tables(); | |
const TableName = 'chocotaco'; | |
await client._doc.transactWrite({ | |
TransactItems: [ | |
{ Delete: { TableName, Key: { email: 'fake@example.com' } } }, | |
{ Delete: { TableName, Key: { email: 'alsofake@example.com' } } }, | |
] | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
>>eval $(cat .env) npm run test:unit | |
> knuckles@0.0.0 test:unit | |
> mocha './src/**/*.test.?(m)js' | |
DynamoDB: UnknownOperationException: UnknownError | |
Using `.transactWrite()` | |
✔ Starts with empty db (509ms) | |
1) Creates new record | |
2) Delete record | |
1 passing (1s) | |
2 failing | |
1) DynamoDB: UnknownOperationException: UnknownError | |
Using `.transactWrite()` | |
Creates new record: | |
UnknownOperationException: UnknownError | |
at throwDefaultError (node_modules/@smithy/smithy-client/dist-cjs/default-error-handler.js:8:22) | |
at /Users/me/code/bust/knuckles/node_modules/@smithy/smithy-client/dist-cjs/default-error-handler.js:18:39 | |
at de_TransactWriteItemsCommandError (node_modules/@aws-sdk/client-dynamodb/dist-cjs/protocols/Aws_json1_0.js:2239:20) | |
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) | |
at async /Users/me/code/bust/knuckles/node_modules/@smithy/middleware-serde/dist-cjs/deserializerMiddleware.js:7:24 | |
at async /Users/me/code/bust/knuckles/node_modules/@aws-sdk/lib-dynamodb/dist-cjs/baseCommand/DynamoDBDocumentClientCommand.js:29:34 | |
at async /Users/me/code/bust/knuckles/node_modules/@aws-sdk/middleware-signing/dist-cjs/awsAuthMiddleware.js:14:20 | |
at async /Users/me/code/bust/knuckles/node_modules/@smithy/middleware-retry/dist-cjs/retryMiddleware.js:27:46 | |
at async /Users/me/code/bust/knuckles/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:7:26 | |
at async Context.<anonymous> (file:///Users/me/code/bust/knuckles/src/shared/db/client/example.test.mjs:39:4) | |
2) DynamoDB: UnknownOperationException: UnknownError | |
Using `.transactWrite()` | |
Delete record: | |
UnknownOperationException: UnknownError | |
at throwDefaultError (node_modules/@smithy/smithy-client/dist-cjs/default-error-handler.js:8:22) | |
at /Users/me/code/bust/knuckles/node_modules/@smithy/smithy-client/dist-cjs/default-error-handler.js:18:39 | |
at de_TransactWriteItemsCommandError (node_modules/@aws-sdk/client-dynamodb/dist-cjs/protocols/Aws_json1_0.js:2239:20) | |
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) | |
at async /Users/me/code/bust/knuckles/node_modules/@smithy/middleware-serde/dist-cjs/deserializerMiddleware.js:7:24 | |
at async /Users/me/code/bust/knuckles/node_modules/@aws-sdk/lib-dynamodb/dist-cjs/baseCommand/DynamoDBDocumentClientCommand.js:29:34 | |
at async /Users/me/code/bust/knuckles/node_modules/@aws-sdk/middleware-signing/dist-cjs/awsAuthMiddleware.js:14:20 | |
at async /Users/me/code/bust/knuckles/node_modules/@smithy/middleware-retry/dist-cjs/retryMiddleware.js:27:46 | |
at async /Users/me/code/bust/knuckles/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:7:26 | |
at async Context.<anonymous> (file:///Users/me/code/bust/knuckles/src/shared/db/client/example.test.mjs:80:4) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment