Define remote methods via model settings/config
Process `settings.methods` and `config.methods` as a key-value map where the key is the method name and the value is an object describing the method in the format expected by strong-remoting. Example: a static method `Model.create` "methods": { "create": { "isStatic": true, "accepts": { "arg": "data", "type": "Car", "http": { "source": "body" } }, "returns": { "arg": "data", "type": "Car", "root": true } } } This patch is based on the code proposed by @mrfelton in #1163.
This commit is contained in:
parent
ce26141d85
commit
f93b69ed0a
|
@ -122,7 +122,7 @@ app.model = function(Model, config) {
|
||||||
Model = registry.createModel(modelConfig);
|
Model = registry.createModel(modelConfig);
|
||||||
|
|
||||||
// delete config options already applied
|
// delete config options already applied
|
||||||
['relations', 'base', 'acls', 'hidden'].forEach(function(prop) {
|
['relations', 'base', 'acls', 'hidden', 'methods'].forEach(function(prop) {
|
||||||
delete config[prop];
|
delete config[prop];
|
||||||
if (config.options) delete config.options[prop];
|
if (config.options) delete config.options[prop];
|
||||||
});
|
});
|
||||||
|
|
|
@ -122,6 +122,8 @@ Registry.prototype.createModel = function(name, properties, options) {
|
||||||
var model = BaseModel.extend(name, properties, options);
|
var model = BaseModel.extend(name, properties, options);
|
||||||
model.registry = this;
|
model.registry = this;
|
||||||
|
|
||||||
|
this._defineRemoteMethods(model, options.methods);
|
||||||
|
|
||||||
// try to attach
|
// try to attach
|
||||||
try {
|
try {
|
||||||
this.autoAttachModel(model);
|
this.autoAttachModel(model);
|
||||||
|
@ -247,6 +249,30 @@ Registry.prototype.configureModel = function(ModelCtor, config) {
|
||||||
'Use `null` or `false` to mark models not attached to any data source.',
|
'Use `null` or `false` to mark models not attached to any data source.',
|
||||||
modelName);
|
modelName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remote methods
|
||||||
|
this._defineRemoteMethods(ModelCtor, config.methods);
|
||||||
|
};
|
||||||
|
|
||||||
|
Registry.prototype._defineRemoteMethods = function(ModelCtor, methods) {
|
||||||
|
if (!methods) return;
|
||||||
|
if (typeof methods !== 'object') {
|
||||||
|
console.warn('Ignoring non-object "methods" setting of "%s".',
|
||||||
|
ModelCtor.modelName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(methods).forEach(function(key) {
|
||||||
|
var meta = methods[key];
|
||||||
|
if (typeof meta.isStatic !== 'boolean') {
|
||||||
|
console.warn('Remoting metadata for "%s.%s" is missing "isStatic" ' +
|
||||||
|
'flag, the method is registered as an instance method.',
|
||||||
|
ModelCtor.modelName,
|
||||||
|
key);
|
||||||
|
console.warn('This behaviour may change in the next major version.');
|
||||||
|
}
|
||||||
|
ModelCtor.remoteMethod(key, meta);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -249,6 +249,30 @@ describe('loopback', function() {
|
||||||
.to.throw(Error, new RegExp('Model not found: ' + uniqueModelName));
|
.to.throw(Error, new RegExp('Model not found: ' + uniqueModelName));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('configures remote methods', function() {
|
||||||
|
var TestModel = loopback.createModel(uniqueModelName, {}, {
|
||||||
|
methods: {
|
||||||
|
staticMethod: {
|
||||||
|
isStatic: true,
|
||||||
|
http: { path: '/static' }
|
||||||
|
},
|
||||||
|
instanceMethod: {
|
||||||
|
isStatic: false,
|
||||||
|
http: { path: '/instance' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var methodNames = TestModel.sharedClass.methods().map(function(m) {
|
||||||
|
return m.stringName.replace(/^[^.]+\./, ''); // drop the class name
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(methodNames).to.include.members([
|
||||||
|
'staticMethod',
|
||||||
|
'prototype.instanceMethod'
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('loopback.createModel(config)', function() {
|
describe('loopback.createModel(config)', function() {
|
||||||
|
@ -449,6 +473,32 @@ describe('loopback', function() {
|
||||||
// configureModel MUST NOT change Model's base class
|
// configureModel MUST NOT change Model's base class
|
||||||
expect(model.settings.base.name).to.equal(baseName);
|
expect(model.settings.base.name).to.equal(baseName);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('configures remote methods', function() {
|
||||||
|
var TestModel = loopback.createModel(uniqueModelName);
|
||||||
|
loopback.configureModel(TestModel, {
|
||||||
|
dataSource: null,
|
||||||
|
methods: {
|
||||||
|
staticMethod: {
|
||||||
|
isStatic: true,
|
||||||
|
http: { path: '/static' }
|
||||||
|
},
|
||||||
|
instanceMethod: {
|
||||||
|
isStatic: false,
|
||||||
|
http: { path: '/instance' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var methodNames = TestModel.sharedClass.methods().map(function(m) {
|
||||||
|
return m.stringName.replace(/^[^.]+\./, ''); // drop the class name
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(methodNames).to.include.members([
|
||||||
|
'staticMethod',
|
||||||
|
'prototype.instanceMethod'
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('loopback object', function() {
|
describe('loopback object', function() {
|
||||||
|
|
Loading…
Reference in New Issue