Come sopra indicato @superkhau, ciascun modello di LoopBack può essere collegato solo a una singola origine dati.
È possibile creare (sottoclasse) un nuovo modello per ogni origine dati che si desidera utilizzare. Quindi è possibile esporre questi modelli per data source tramite URL REST univoci oppure implementare un modello wrapper che invierà i metodi al modello specifico dell'origine dati corretto.
Nel mio esempio, mostrerò come esporre i modelli per-datasource per un modello Car
collegato a db
e anotherdb
. Il modello Car
è definito nel solito modo tramite common/models/car.json
e common/models/car.js
.
Ora è necessario definire per-datasource modelli:
// common/models/car-db.js
{
"name": "Car-db",
"base": "Car",
"http": {
"path": "/cars:db"
}
}
// common/models/car-anotherdb.js
{
"name": "Car-anotherdb",
"base": "Car",
"http": {
"path": "/cars:anotherdb"
}
}
// server/model-config.json
{
"Car": {
"dataSource": "default"
},
"Car-db": {
"dataSource": "db"
},
"Car-anotherdb": {
"dataSource": "anotherdb"
}
}
Ora avete i seguenti URL disponibili:
GET /api/Cars:db
GET /api/Cars:anotherdb
GET /api/Cars
La soluzione sopra delineato ha due limitazioni: è necessario definire un nuovo il modello per ogni origine dati e l'origine dati non possono essere selezionati utilizzando un parametro di query.
Per risolvere ciò, è necessario un approccio diverso. Immagino di nuovo che ci sia un modello Car
già definito.
Ora è necessario creare un "dispatcher".
// common/models/car-dispatcher.json
{
"name": "CarDispatcher",
"base": "Model", //< important!
"http": {
"path": "/cars"
}
}
// common/models/car-dispatcher.js
var loopback = require('loopback').PersistedModel;
module.exports = function(CarDispatcher) {
Car.find = function(ds, filter, cb) {
var model = this.findModelForDataSource(ds);
model.find(filter, cb);
};
// a modified copy of remoting metadata from loopback/lib/persisted-model.js
Car.remoteMethod('find', {
isStatic: true,
description: 'Find all instances of the model matched by filter from the data source',
accessType: 'READ',
accepts: [
{arg: 'ds', type: 'string', description: 'Name of the datasource to use' },
{arg: 'filter', type: 'object', description: 'Filter defining fields, where, orderBy, offset, and limit'}
],
returns: {arg: 'data', type: [typeName], root: true},
http: {verb: 'get', path: '/'}
});
// TODO: repeat the above for all methods you want to expose this way
Car.findModelForDataSource = function(ds) {
var app = this.app;
var ds = ds && app.dataSources[ds] || app.dataSources.default;
var modelName = this.modelName + '-' + ds;
var model = loopback.findModel(modelName);
if (!model) {
model = loopback.createModel(
modelName,
{},
{ base: this.modelName });
}
return model;
};
};
Il bit finale è quello di rimuovere Car
e utilizzare CarDispatcher
nel modello di configurazione:
// server/model-config.json
{
"CarDispatcher": {
dataSource: null,
public: true
}
}