2014-11-25 13 views
6

Ho definito diversi modelli che utilizzano un datasource "db" (mysql) per il mio ambiente.loopbackjs: collegare un modello a origini dati diverse

C'è un modo per avere più origini dati collegate a tali modelli, quindi sarei in grado di eseguire operazioni di REST su database diversi?

vale a dire:?? GET/api/cose ds = "db"

GET/API/cose ds = "anotherdb"

GET/API/Cose (utilizzerà ds di default)

risposta

6

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 
    } 
} 
1

Per impostazione predefinita, è possibile allegare solo origini dati su base per modello. Significa che puoi collegare ciascun modello a una diversa fonte di dati tramite datasources.json.

Per il tuo caso di utilizzo, dovrai aggiungere un gancio remoto a ciascun endpoint che desideri per più origini dati. Nel tuo gancio a distanza, si farà qualcosa di simile:

... 
var ds1 = Model.app.dataSources.ds1; 
var ds2 = Model.app.dataSources.ds2; 

//some logic to pick a data source 
if (context.req.params... 
... 

Vedi http://docs.strongloop.com/display/LB/Remote+hooks per maggiori informazioni.

Problemi correlati