https://github.com/luckydrq/rdb-dataloader
Better dataloader for ralational database such as mysql
https://github.com/luckydrq/rdb-dataloader
dataloader rdb
Last synced: 8 months ago
JSON representation
Better dataloader for ralational database such as mysql
- Host: GitHub
- URL: https://github.com/luckydrq/rdb-dataloader
- Owner: luckydrq
- Created: 2017-01-25T01:55:09.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2017-10-24T08:59:48.000Z (over 8 years ago)
- Last Synced: 2025-07-01T10:48:26.047Z (12 months ago)
- Topics: dataloader, rdb
- Language: JavaScript
- Homepage:
- Size: 10.7 KB
- Stars: 8
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: History.md
Awesome Lists containing this project
README
# rdb-dataloader
[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![Test coverage][codecov-image]][codecov-url]
[![David deps][david-image]][david-url]
[![Known Vulnerabilities][snyk-image]][snyk-url]
[![npm download][download-image]][download-url]
This module targets at [relational database](https://en.wikipedia.org/wiki/Relational_database) such as MySQL, SQL Server. Heavily inspired by Facebook [DataLoader](https://github.com/facebook/dataloader/issues).
[npm-image]: https://img.shields.io/npm/v/rdb-dataloader.svg?style=flat-square
[npm-url]: https://npmjs.org/package/rdb-dataloader
[travis-image]: https://img.shields.io/travis/luckydrq/rdb-dataloader/master.svg?style=flat-square
[travis-url]: https://travis-ci.org/luckydrq/rdb-dataloader
[codecov-image]: https://codecov.io/gh/luckydrq/rdb-dataloader/branch/master/graph/badge.svg
[codecov-url]: https://codecov.io/gh/luckydrq/rdb-dataloader
[david-image]: https://img.shields.io/david/luckydrq/rdb-dataloader.svg?style=flat-square
[david-url]: https://david-dm.org/luckydrq/rdb-dataloader
[snyk-image]: https://snyk.io/test/npm/rdb-dataloader/badge.svg?style=flat-square
[snyk-url]: https://snyk.io/test/npm/rdb-dataloader
[download-image]: https://img.shields.io/npm/dm/rdb-dataloader.svg?style=flat-square
[download-url]: https://npmjs.org/package/rdb-dataloader
## Install
`$ npm i rdb-dataloader`
## Why?
First i'd like to say [DataLoader](https://github.com/facebook/dataloader/issues) is a great module that, like it's said, aims to provide per-request cache to save network IO and extremly useful for data service implemented by [GraphQL](http://graphql.org) which intergreted with my project recently. I use MySQL as data storage layer which is a common case in real world i believe. However, I found something inconvenient when playing with MySQL:
### Unnecessary duplicate cache
It is common to have one or more unique key(s) in a table. For example,
an User table with these fields: `id`, `name`, `mobile` can have
`id` as the [Primary Key](http://wiki.c2.com/?PrimaryKey) and `mobile`
as a [Unique Key](https://en.wikipedia.org/wiki/Unique_key). So the data service has to response to `fetchByIds` and `fetchByMobiles` calls. Then it
have to initiate two instances when using [DataLoader](https://github.com/facebook/dataloader):
```js
const DataLoader = require('dataloader');
const idLoader = new DataLoader(fetchByIds);
const mobileLoader = new DataLoader(fetchByMobiles);
idLoader.load(1);
mobileLoader.load('+86123456');
function fetchByIds(ids) {
return db.Users.getByIds(ids);
}
function fetchByMobiles(mobiles) {
return db.Users.getByMobiles(mobiles);
}
```
This can work but it's not good enough and the logic is far more complex
in real world. Two instances meaning two separate [cache](https://github.com/facebook/dataloader/blob/master/src/index.js#L56), you can imagine
that there would be many duplecate records cached in both instance
cache just because they are fetched by a different key(`id` or
`mobile`) and *Network Still happens for both sides*. Also there would be more instances to initiate as the number
of unique keys increases.
### Duplicate keys
There is an old [issue](https://github.com/facebook/dataloader/issues/49) and [DataLoader](https://github.com/facebook/dataloader) fixes now.
## What does this module address?
This module aims to solve the inconvenience metioned above when playing with relational database. *It is recommended that one loader per table.* It'd use a single cache and whenever a record is fetched by PK or UK, it'd `contribute` to the cache. Accordingly, it'd support load by PK or UK to take full advantage of cache.
## Example
```js
const uniqueKeyMap = new Map();
uniqueKeyMap.set('name', db.fetchByNames); // UK
uniqueKeyMap.set('email', db.fetchByEmails); // UK
const loader = new DataLoader(db.fetchByIds, { uniqueKeyMap });
loader.load('luckydrq', 'name') // the second argument `name` is to tell loader to fetchByNames
.then(record => {
assert(record.id === 1);
assert(loader._promiseCache.size === 1);
done();
}).catch(done);
```
More [examples](https://github.com/luckydrq/rdb-dataloader/blob/master/test/index.test.js).
## API
Since this module inherits from [DataLoader](https://github.com/facebook/dataloader), it is compatible with the apis of DataLoader. But as you can see from former example, the api is extended. Extended apis are the following:
### contructor(options)
The constructor accepts all the options that DataLoader accepts. `options.cache = true` and `options.batch = true` is set by default and there is no way to override it because it'd be useless without these two features disabled. Alse, there are additional options as below:
- options.primaryKey(optional): String
Specify PK name, default is "id";
- options.uniqueKeyMap(optional): ES6 Map
- key: String
UK name
- value: Function
Batch function for UK
Use it when you want to fetch by UK.
### load(key[, uniqueKey])
If you want to load by UK, the second argument should be specified, omitted meaning load by PK.
### loadMany(keys[, uniqueKey])
If you want to load by UK, the second argument should be specified, omitted meaning load by PK.
## Lisence
MIT