Sequelize model based service, exposes basic CRUD methods, pub/sub mechanisms, computed properties through decorations.
node >= 7.10
typescript >= 2.4
inversify >= 4.13
npm i inversify reflect-metadata @bluejay/sequelize-service
Creating a SequelizeService
The only required dependency is a Sequelize model.
TUserWritePropertiesis an interface describing a user's properties used during write and update operations. It is recommended to require properties that are required to create the object and leaving the others as optional.
TUserReadPropertiesis an interface describing a user's properties used during read operations. It is recommend to define as readonly.
TUserComputedPropertiesis an interface describing the possible computed properties for a user object.
UserModelis the User Sequelize model.
// TUserReadProperties is the most inclusive interface, describing all the fields from the User schema// ---// Make sure to declare the service as a singleton to ensure events are caught by all subscriberscontainer.bindID.UserService.toUserService.inSingletonScope;
All hooks and many methods receive a
Session object which provides various handful methods to deal with a set of data, in a particular context.
Session inherits from Collection, so you can manipulate/iterate data asynchronous without the need of external libraries.
Sessions also expose various methods related to the type of query you're currently dealing with. For example during an update:
You might notice that this documentation never refers to particular instances, this is because this entire module is based on sessions, which in turn encourage you to think all queries as bulk operations, and therefore optimize for multiple objects.
All methods returning multiple objects return a Collection. Methods returning a single return an unwrapped object.
Creating a single object
;console.loguser.email; // email@example.com
Creating multiple objects
// Find multiple users;// Find a single user by its primary key;// Find multiple users by their primary key;
// Change the user email to another valueawait userService.update, ;// Target a user by primary keyawait userService.updateByPrimaryKey1, ;
Upserting an obejct
Caution: This methods will lock the "candidate" row, and perform either a
create or an
update depending on if a candidate was found.
Note: For consistency, the created/updated row is always returned, meaning that we perform a SELECT after the update, if necessary.
This method uses a more MongoDB like syntax, allowing you to pass complex filters as part of the matching criteria.
// Make sure a user older than 21 existsawait userService.replaceOne, ;
// Remove all users younger than 21await userService.delete;
Working with transactions
Note: All writing methods automatically create a transaction, which encapsulates both the hooks and the model call itself, meaning that if an
afterCreate hooks fails, for example, the entire creation will be rolled back,.
Creating a transaction
Within your service, the
transaction() method allows you to create a new transaction.
return await this.transaction,;
Ensuring a transaction
There are times when you want to make sure you're running under a transaction, but not necessarily create a new one, if, for example, your current method's caller already created one.
transaction() method takes an
options parameter, which may contain a
transaction property, in which the transaction will be reused.
return await this.transaction,;
Passing transactions to methods
All query methods accept an optional
await userService.find, ;await userService.create, ;
Working with hooks
Hooks are a convenient way to validate and transform you data.
Hooks are ran for all write queries, before and after the query.
Working with events
Computed properties allow you to decorate objects with properties that are not stored in your DB.
Computed properties are instances of the abstract
ComputedProperty class and must implement their
transform method, which takes a
Session as an argument.
To make your service aware of the computed properties, you need to create a manager:
And finally you can set the manager on your service:
You can now request
isAdult to be computed using the
See Github Pages.