feat: remove DynamodbWrapper client dependency#32
Conversation
src/with-paginator-helper.js
Outdated
| } | ||
| } | ||
|
|
||
| result.Items = items; |
There was a problem hiding this comment.
You may want to update the other fields that refer to the amount of items read (like count or consumed capacity)
There was a problem hiding this comment.
Good catch, I forgot about the Count, ScannedCount and ConsumedCapacity
nfantone
left a comment
There was a problem hiding this comment.
Thanks for this! Left some comments here and there. The only bits and blobs I see missing are the batchWrite operations which would now behave differently after the removal on dynamodb-wrapper. Not really sold on keeping current functionality, though - so opening the discussion. We might as well cut a new major release and make flynamo be on par with the official AWS.DynamoDB client.
src/get-all.js
Outdated
| const addTableName = require('./table-name'); | ||
| const withPaginatorHelper = require('./with-paginator-helper'); | ||
|
|
||
| const DEFAULT_OPTIONS = { |
There was a problem hiding this comment.
I'd freeze this object and add docs to the props.
const DEFAULT_OPTIONS = Object.freeze({ ... });
src/get-all.js
Outdated
| autopagination: true, | ||
| raw: false | ||
| }; | ||
| const mergeWithDefaults = mergeRight(DEFAULT_OPTIONS); |
There was a problem hiding this comment.
This kinda works, but won't default to values in DEFAULT_OPTIONS for null, undefined or empty properties. Maybe remove those before merging?
const mergeWithDefaults = compose(mergeRight(DEFAULT_OPTIONS), rejectNilOrEmpty);There was a problem hiding this comment.
- If the user put a nil value, why this should change it?
- I can add the _ rejectNilOrEmpty_ but we don't have ramda-land here, do see that is necessary to add another dependency just for this?
src/get-all.test.js
Outdated
|
|
||
| test('should return `undefined` if no items are returned', async () => { | ||
| const mockScan = jest.fn().mockResolvedValue({}); | ||
| test('should return `[]` if no items are returned', async () => { |
There was a problem hiding this comment.
While I agree [] makes more sense, this would be a breaking change.
There was a problem hiding this comment.
I revert this change to return undefined instead
src/count.js
Outdated
| * @private | ||
| */ | ||
| const createCount = scan => pipeP(scan, prop('Count')); | ||
| const createCount = scan => params => withPaginatorHelper(scan, params, true).then(prop('Count')); |
There was a problem hiding this comment.
I like the simplicity of what we had before. Maybe we could make the withPaginatorHelper return an async function that expects params? (see comment further below)
| const createCount = scan => params => withPaginatorHelper(scan, params, true).then(prop('Count')); | |
| const createCount = scan => compose(andThen(prop('Count')), withPaginator(scan)); |
| * @private | ||
| */ | ||
| const createGetAll = scan => pipeP(scan, unwrapAll('Items')); | ||
| const createGetAll = scan => (params, options = {}) => { |
There was a problem hiding this comment.
Following the idea of having the paginator helper return a function accepting params, this could be turned into something like:
const createGetAll = scan => (params, options = {}) => {
const { raw, autopagination } = mergeWithDefaults(options);
const scanFn = autopagination ? withPaginator(scan) : scan;
return scanFn(params).then(
raw ? unwrapOverAll('Items') : unwrapAll('Items')
);
};
src/get.js
Outdated
| */ | ||
| const getUnwrappedItem = getItem => pipeP(apply(getItem), unwrapProp('Item')); | ||
| const getUnwrappedItem = getItem => | ||
| compose(andThen(unwrapProp('Item')), request => request.promise(), apply(getItem)); |
There was a problem hiding this comment.
Since this is now used everywhere, what about adding some helpers including a swap in replacement for andThen that automatically invokes request.promise() first?
'use strict';
const R = require('ramda');
/**
* Invokes `promise` on the given object passing
* in no arguments.
*
* @param {object} obj The obj to invoke `promise` on.
* @returns {Promise.<*>} A `Promise` as returned by a call to `promise`.
*/
const toPromise = R.invoker(0, 'promise')
/**
* Returns the result of applying an `fn` function to the value inside a fulfilled promise,
* after having invoked `promise()` on the target object.
*
* @private
* @see https://ramdajs.com/docs/#andThen
* @param {Function} fn The function to apply. Can return a value or a promise of a value.
*/
const andThen = fn => compose(
R.andThen(fn),
toPromise
);
module.exports = { toPromise, andThen };
src/query.js
Outdated
| const addTableName = require('./table-name'); | ||
| const withPaginatorHelper = require('./with-paginator-helper'); | ||
|
|
||
| const DEFAULT_OPTIONS = { |
There was a problem hiding this comment.
Same as the scan comments above.
src/with-paginator-helper.js
Outdated
| if (autopagination) { | ||
| while (result.LastEvaluatedKey) { | ||
| result = await methodFn({ ...params, ExclusiveStartKey: result.LastEvaluatedKey }).promise(); | ||
| result.Items && result.Items.length >= 0 && items.push(...result.Items); |
There was a problem hiding this comment.
| result.Items && result.Items.length >= 0 && items.push(...result.Items); | |
| isNotNilOrEmpty(result.Items) && items.push(...result.Items); |
src/with-paginator-helper.js
Outdated
| * @param {boolean} autopagination Whether to return all the records from DynamoDB or just the first batch of records. | ||
| * @returns {Promise} A promise that resolves to the response from DynamoDB. | ||
| */ | ||
| async function withPaginatorHelper(methodFn, params, autopagination) { |
There was a problem hiding this comment.
I'd turn this into a factory function expecting an operationFn and returning another function that takes in only input as argument ("operation" and "input" as that's what the AWS.DynamoDB typings typically calls them). The autopagination bit seems redundant to me.
function withPaginator(operationFn) {
async function autopaginate(input) { /* ... */ }
return autopaginate;
}|
What the wrapper is doing for those cases is to be able to do an unlimited amount of request to the database taking care of the 25 request limit that the aws-sdk client has. Thoughts? |
|
➿ Code coverage
|
@lfantone we may need to drop the dependency because it's blocking the upgrade to aws-sdk v3. Maybe we can bring the implementation for the batch methods to flynamo itself? |
|
Yes, feel free to remove it |
No description provided.