Skip to content

Instantly share code, notes, and snippets.

@shubhamp-sf
Last active March 14, 2023 07:25
Show Gist options
  • Save shubhamp-sf/ceee5d9a49d17be977d1c7cb33652ad6 to your computer and use it in GitHub Desktop.
Save shubhamp-sf/ceee5d9a49d17be977d1c7cb33652ad6 to your computer and use it in GitHub Desktop.

Univeral Mixin for the Good

This approach is written keeping loopback4-soft-delete codebase in mind but should work for others having similar structure. Ideally when the only thing that class/mixin does is calling super.someMethod and is to be used with two or more different parent classes.

TLDR of the Solution

Remove all classes providing soft-crud for different underlying repository, change the type of base class being accepted by mixin to an explicit interface that only includes methods/properties that are actually of use in the mixin's code.)

Current Structure

The main exports in the package are SoftCrudRepositoryMixin, the SoftCrudRepository class and one for transaction repo. Aiming to serve the same purpose with different underlying class but with mixin it's possible to pass any other class as base having similar interface as DefaultCrudRepository from loopback.

Recently a requirement arrived to make it compatible to somewhat different repository from loopback4-sequelize package called SequelizeCrudRepository. It doesn't completely follows the DefaultCrudRepository's interface as it lacks some irrelevant properties, preventing user from using the mixin wrapping sequelize repository.

What we ended up doing is to solve this is, we created a copy of the soft-delete logic code and created new class similar to SoftCrudRepository by just replacing the extended class to the sequelize one and exported it as SequelizeSoftCrudRepository.

The issue with above approach

This brought up major challenge when it comes to maintaining the code. Like any bug fix or any sort of change is supposed to be made in all four places (mixin, main soft crud, transaction repo and sequelize soft crud repo) plus the additional effort for every change in respective test cases as well. More than maintainability, users won't be able to utilize soft-delete capabilities in any custom class like the sequelize one that doesn't have all the props like default crud repo, due to the strictness of mixin accepting DefaultCrudRepository constructor as a base class's type (where as the mixin only needs few methods to work correctly namelyfindOne, findById, find, updateAll, updateById, deleteById, deleteAll and count ).

The possible solution

By behaviour the soft-delete package only adds extra logic before calling the main crud methods. Like modifying the where filter before the super.find is invoked. It doesn't care if the base class received is DefaultCurdRepository or the transaction repo or the sequelize one. All it wants is that, it should have a find method (and few others) that it can call. So having the type more explicit than Constructor<DefaultCrudRepository> would be more flexible and would cover all the extension cases for Transaction, Sequelize and others we may encounter in future. Doing so will eliminate the need of exporting other classes as everyone can use the mixin universally for each of current and future use cases. Leading us to have no duplicate code. Wohooo! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment