@northernv/dataloader
v1.2.0
Published
A framework for dataloaders in models
Downloads
7
Readme
@northernv/dataloader
Usage
npm install -S @northernv/dataloader;
yarn add @northernv/dataloader;
In your models, that are Javascript classes, include a static function called loaders
that returns an object of dataloaders
class Property {
static loaders (DataLoader, { db }) {
const manyPropertyById = new DataLoader(propertyIds => {
return db('property').whereIn('id', propertyIds)
.then(rows => propertyIds.map(id => rows.filter(x => x.id === id)))
})
const manyPropertyByAssociationId = new DataLoader(associationIds => {
return db('property').whereIn('property.assocation_id', associationIds)
.then(rows => associationIds.map(id => rows.filter(x => x.assocationId === id)))
})
const onePropertyById = new DataLoader(propertyIds => {
return db('property').whereIn('id', propertyIds)
.then(rows => propertyIds.map(id => rows.find(x => x.id === id)))
})
return { manyPropertyById, manyPropertyByAssociationId, onePropertyById }
}
}
Each loader should follow the patter one<ClassName>By<PropertyName>
or many<ClassName>By<PropertyName>
In your bootstrapping file
const loader = dataloaders('models', { db })
const server = new ApolloServer({
schema,
// Create new Dataloaders for each request
context: ({ req, res }) => new Context({ req, res, db, channel, loaders: loader() }),
formatError: (error) => {
Sentry.captureException(error)
return { ...error, code: get(error, 'originalError.constructor.name', 'Unknown') }
},
})
or you can delay adding the db
option until runtime
// Notice here we do not pass in the run time option `db`
const loader = dataloaders('models')
const server = new ApolloServer({
schema,
// Create new Dataloaders for each request
// Instead we pass in the runtime option `db` here on init
context: ({ req, res }) => new Context({ req, res, db, channel, loaders: loader({ db }) }),
formatError: (error) => {
Sentry.captureException(error)
return { ...error, code: get(error, 'originalError.constructor.name', 'Unknown') }
},
})
See how we pass in the model
directory that is relative to the project root and our options. The options will be passed to each of the loaders
functions
Notes
- It will throw an error if there are two loaders with the same name, so sticking to the naming convention is important.
- Many loaders use
filter
, while One loaders userfind
- It assumes that items are loaded from a database