Skip to content
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

Modernize examples in readme #213

Merged
merged 2 commits into from Nov 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
98 changes: 52 additions & 46 deletions README.md
Expand Up @@ -53,9 +53,9 @@ Batching is not an advanced feature, it's DataLoader's primary feature.
Create loaders by providing a batch loading function.

```js
var DataLoader = require('dataloader')
const DataLoader = require('dataloader')

var userLoader = new DataLoader(keys => myBatchGetUsers(keys));
const userLoader = new DataLoader(keys => myBatchGetUsers(keys))
```

A batch loading function accepts an Array of keys, and returns a Promise which
Expand All @@ -66,14 +66,14 @@ individual loads which occur within a single frame of execution (a single tick
of the event loop) and then call your batch function with all requested keys.

```js
userLoader.load(1)
.then(user => userLoader.load(user.invitedByID))
.then(invitedBy => console.log(`User 1 was invited by ${invitedBy}`));
const user = await userLoader.load(1)
const invitedBy = await userLoader.load(user.invitedByID)
console.log(`User 1 was invited by ${invitedBy}`)

// Elsewhere in your application
userLoader.load(2)
.then(user => userLoader.load(user.lastInvitedID))
.then(lastInvited => console.log(`User 2 last invited ${lastInvited}`));
const user = await userLoader.load(2)
const lastInvited = await userLoader.load(user.lastInvitedID)
console.log(`User 2 last invited ${lastInvited}`)
```

A naive application may have issued four round-trips to a backend for the
Expand Down Expand Up @@ -144,9 +144,9 @@ In addition to relieving pressure on your data storage, caching results per-requ
also creates fewer objects which may relieve memory pressure on your application:

```js
var userLoader = new DataLoader(...)
var promise1A = userLoader.load(1)
var promise1B = userLoader.load(1)
const userLoader = new DataLoader(...)
const promise1A = userLoader.load(1)
const promise1B = userLoader.load(1)
assert(promise1A === promise1B)
```

Expand All @@ -172,11 +172,11 @@ function createLoaders(authToken) {
}
}

var app = express()
const app = express()

app.get('/', function(req, res) {
var authToken = authenticateUser(req)
var loaders = createLoaders(authToken)
const authToken = authenticateUser(req)
const loaders = createLoaders(authToken)
res.send(renderPage(req, loaders))
})

Expand All @@ -195,18 +195,17 @@ Here's a simple example using SQL UPDATE to illustrate.

```js
// Request begins...
var userLoader = new DataLoader(...)
const userLoader = new DataLoader(...)

// And a value happens to be loaded (and cached).
userLoader.load(4).then(...)
const user = await userLoader.load(4)

// A mutation occurs, invalidating what might be in cache.
sqlRun('UPDATE users WHERE id=4 SET username="zuck"').then(
() => userLoader.clear(4)
)
await sqlRun('UPDATE users WHERE id=4 SET username="zuck"')
userLoader.clear(4)

// Later the value load is loaded again so the mutated data appears.
userLoader.load(4).then(...)
const user = await userLoader.load(4)

// Request completes.
```
Expand All @@ -221,12 +220,14 @@ be cached to avoid frequently loading the same `Error`.
In some circumstances you may wish to clear the cache for these individual Errors:

```js
userLoader.load(1).catch(error => {
if (/* determine if should clear error */) {
userLoader.clear(1);
try {
const user = await userLoader.load(1)
} catch (error) {
if (/* determine if the error should not be cached */) {
userLoader.clear(1)
}
throw error;
});
throw error
}
```

#### Disabling Cache
Expand All @@ -244,7 +245,7 @@ for each instance of the requested key.
For example:

```js
var myLoader = new DataLoader(keys => {
const myLoader = new DataLoader(keys => {
console.log(keys)
return someBatchLoadFn(keys)
}, { cache: false })
Expand All @@ -263,7 +264,7 @@ enabled, but will immediately clear its cache when the batch function is called
so later requests will load new values.

```js
var myLoader = new DataLoader(keys => {
const myLoader = new DataLoader(keys => {
identityLoader.clearAll()
return someBatchLoadFn(keys)
})
Expand Down Expand Up @@ -310,16 +311,16 @@ Loads a key, returning a `Promise` for the value represented by that key.
Loads multiple keys, promising an array of values:

```js
var [ a, b ] = await myLoader.loadMany([ 'a', 'b' ]);
const [ a, b ] = await myLoader.loadMany([ 'a', 'b' ])
```

This is equivalent to the more verbose:

```js
var [ a, b ] = await Promise.all([
const [ a, b ] = await Promise.all([
myLoader.load('a'),
myLoader.load('b')
]);
])
```

- *keys*: An array of key values to load.
Expand Down Expand Up @@ -378,7 +379,7 @@ When using DataLoader, we could define the `User` type using the
and possibly fewer if there are cache hits.

```js
var UserType = new GraphQLObjectType({
const UserType = new GraphQLObjectType({
name: 'User',
fields: () => ({
name: { type: GraphQLString },
Expand All @@ -391,9 +392,12 @@ var UserType = new GraphQLObjectType({
first: { type: GraphQLInt }
},
type: new GraphQLList(UserType),
resolve: (user, { first }) => queryLoader.load([
'SELECT toID FROM friends WHERE fromID=? LIMIT ?', user.id, first
]).then(rows => rows.map(row => userLoader.load(row.toID)))
resolve: async (user, { first }) => {
const rows = await queryLoader.load([
'SELECT toID FROM friends WHERE fromID=? LIMIT ?', user.id, first
])
return rows.map(row => userLoader.load(row.toID))
}
}
})
})
Expand All @@ -415,15 +419,15 @@ function createLoaders(authToken) {
users: new DataLoader(ids => genUsers(authToken, ids)),
cdnUrls: new DataLoader(rawUrls => genCdnUrls(authToken, rawUrls)),
stories: new DataLoader(keys => genStories(authToken, keys)),
};
}
}

// When handling an incoming web request:
var loaders = createLoaders(request.query.authToken);
const loaders = createLoaders(request.query.authToken)

// Then, within application logic:
var user = await loaders.users.load(4);
var pic = await loaders.cdnUrls.load(user.rawPicUrl);
const user = await loaders.users.load(4)
const pic = await loaders.cdnUrls.load(user.rawPicUrl)
```

Creating an object where each key is a `DataLoader` is one common pattern which
Expand All @@ -438,19 +442,21 @@ value. If the same user is loaded by both keys, then it may be useful to fill
both caches when a user is loaded from either source:

```js
let userByIDLoader = new DataLoader(ids => genUsersByID(ids).then(users => {
const userByIDLoader = new DataLoader(async ids => {
const users = await genUsersByID(ids)
for (let user of users) {
usernameLoader.prime(user.username, user);
usernameLoader.prime(user.username, user)
}
return users;
}));
return users
})

let usernameLoader = new DataLoader(names => genUsernames(names).then(users => {
const usernameLoader = new DataLoader(async names => {
const users = await genUsernames(names)
for (let user of users) {
userByIDLoader.prime(user.id, user);
userByIDLoader.prime(user.id, user)
}
return users;
}));
return users
})
```


Expand Down
20 changes: 9 additions & 11 deletions examples/CouchDB.md
Expand Up @@ -8,13 +8,13 @@ This example uses the [nano][] CouchDB client which offers a `fetch` method
supporting the bulk document API.

```js
var DataLoader = require('dataloader');
var nano = require('nano');
const DataLoader = require('dataloader');
const nano = require('nano');

var couch = nano('http://localhost:5984');
const couch = nano('http://localhost:5984');

var userDB = couch.use('users');
var userLoader = new DataLoader(keys => new Promise((resolve, reject) => {
const userDB = couch.use('users');
const userLoader = new DataLoader(keys => new Promise((resolve, reject) => {
userDB.fetch({ keys: keys }, (error, docs) => {
if (error) {
return reject(error);
Expand All @@ -25,12 +25,10 @@ var userLoader = new DataLoader(keys => new Promise((resolve, reject) => {

// Usage

var promise1 = userLoader.load('8fce1902834ac6458e9886fa7f89c0ef');
var promise2 = userLoader.load('00a271787f89c0ef2e10e88a0c00048b');

Promise.all([ promise1, promise2 ]).then(([ user1, user2]) => {
console.log(user1, user2);
});
const promise1 = userLoader.load('8fce1902834ac6458e9886fa7f89c0ef');
const promise2 = userLoader.load('00a271787f89c0ef2e10e88a0c00048b');
const [ user1, user2 ] = await Promise.all([ promise1, promise2 ])
console.log(user1, user2);
```

[nano]: https://github.com/dscape/nano
6 changes: 3 additions & 3 deletions examples/GoogleDatastore.md
Expand Up @@ -10,16 +10,16 @@ const Datastore = require('@google-cloud/datastore');

const datastore = new Datastore();

const datastoreLoader = new DataLoader(keys =>
datastore.get(keys).then(results => {
const datastoreLoader = new DataLoader(async keys => {
const results = await datastore.get(keys)
// Sort resulting entities by the keys they were requested with.
const entities = results[0];
const entitiesByKey = {};
entities.forEach(entity => {
entitiesByKey[JSON.stringify(entity[datastore.KEY])] = entity;
});
return keys.map(key => entitiesByKey[JSON.stringify(key)] || null);
}),
},
{
// Datastore complex keys need to be converted to a string for use as cache keys
cacheKeyFn: key => JSON.stringify(key),
Expand Down
10 changes: 5 additions & 5 deletions examples/Knex.md
Expand Up @@ -14,7 +14,7 @@ const db = require('./db'); // an instance of Knex client

// The list of data loaders

const data = {
const loaders = {
user: new DataLoader(ids => db.table('users')
.whereIn('id', ids).select()
.then(rows => ids.map(id => rows.find(x => x.id === id)))),
Expand All @@ -30,10 +30,10 @@ const data = {

// Usage

Promise.all([
data.user.load('1234'),
data.storiesByUserId.load('1234'),
]).then(([user, stories]) => {/* ... */});
const [user, stories] = await Promise.all([
loaders.user.load('1234'),
loaders.storiesByUserId.load('1234'),
])
```

For a complete example visit [kriasoft/nodejs-api-starter][nsk].
Expand Down
8 changes: 4 additions & 4 deletions examples/Redis.md
Expand Up @@ -7,12 +7,12 @@ with DataLoader.
Here we build an example Redis DataLoader using [node_redis][].

```js
var DataLoader = require('dataloader');
var redis = require('redis');
const DataLoader = require('dataloader');
const redis = require('redis');

var client = redis.createClient();
const client = redis.createClient();

var redisLoader = new DataLoader(keys => new Promise((resolve, reject) => {
const redisLoader = new DataLoader(keys => new Promise((resolve, reject) => {
client.mget(keys, (error, results) => {
if (error) {
return reject(error);
Expand Down