6
votes

I am using loopback without the strongloop framework itself, meaning I have no access to any of the cli tools. I am able to succesfully create and launch a loopback server and define/load some models in this fashion:

var loopback = require('loopback');
var app = loopback();

var dataSource = app.dataSource
(
    'db',
    {
        adapter : 'memory'
    });
);

var UserModel = app.loopback.findModel('User');
UserModel.attachTo(dataSource);
app.model(UserModel);

/* ... other models loading / definitions */

// Expose API
app.use('/api', app.loopback.rest());

What I would like to achieve is to be able to detach a model from the loopback application at runtime, so it is not available from the rest API nor the loopback object anymore (without the need to restart the node script).

I know it is possible to remove a model definition made previously from the cli: Destroy a model in loopback.io, but this is not valid in my case since what it does is to remove the json objects that are loaded at strongloop boot, which is not applicable here.

I would appreciate very much any help regarding this, I have found nothing in the strongloop API documentation.

2

2 Answers

1
votes

Disclaimer: I am a core developer of LoopBack.

I am afraid there is no easy way for deleting models at runtime, we are tracking this request in issue #1590.

so it is not available from the rest API nor the loopback object anymore

Let's take a look at the REST API first. In order to remove your model from the REST API, you need to remove it from the list of "shared classes" maintained by strong-remoting and then clean the cached handler middleware.

delete app.remotes()._classes[modelName];
delete app.remotes()._typeRegistry._types[modelName];
delete app._handlers.rest;

When the next request comes in, LoopBack will create a new REST handler middleware and rebuild the routing table.

In essence, you need to undo the work done by this code.

In order to remove the model from LoopBack JavaScript APIs, you need to remove it from the list of models maintained by application's registry:

delete app.models[modelName];
delete app.models[classify(modelName)];
delete app.models[camelize(modelName)];
app.models.models.splice(app.models.indexOf(ModelCtor), 1);

(This is undoing the work done by this code).

Next, you need to remove it from loopback-datasource-juggler registries:

delete app.registry.modelBuilder.models[modelName];

Caveats:

  • I haven't run/tested this code, it may not work out of the box.
  • It does not handle the case where the removed model has relations with other models.
  • It does not notify loopback-component-explorer about the change in the API