The App
object represents a Loopback application.
The App object extends Express and supports Express / Connect middleware. See Express documentation for details.
var loopback = require('loopback');
var app = loopback();
app.get('/', function(req, res){
res.send('hello world');
});
app.listen(3000);
Initialize an application from an options object or a set of JSON and JavaScript files.
This function takes an optional argument that is either a string or an object.
If the argument is a string, then it sets the application root directory based on the string value. Then it:
datasources.json
file in the application root directory.models.json
file in the application root directory.If the argument is an object, then it looks for model
, dataSources
, and appRootDir
properties of the object.
If the object has no appRootDir
property then it sets the current working directory as the application root directory.
Then it:
options.dataSources
object.options.models
object.In both cases, the function loads JavaScript files in the /models
and /boot
subdirectories of the application root directory with require()
.
NOTE: mixing app.boot()
and app.model(name, config)
in multiple
files may result in models being undefined due to race conditions.
To avoid this when using app.boot()
make sure all models are passed as part of the models
definition.
Throws an error if the config object is not valid or if boot fails.
The following is example JSON for two Model
definitions: "dealership" and "location".
{
"dealership": {
// a reference, by name, to a dataSource definition
"dataSource": "my-db",
// the options passed to Model.extend(name, properties, options)
"options": {
"relations": {
"cars": {
"type": "hasMany",
"model": "Car",
"foreignKey": "dealerId"
}
}
},
// the properties passed to Model.extend(name, properties, options)
"properties": {
"id": {"id": true},
"name": "String",
"zip": "Number",
"address": "String"
}
},
"car": {
"dataSource": "my-db"
"properties": {
"id": {
"type": "String",
"required": true,
"id": true
},
"make": {
"type": "String",
"required": true
},
"model": {
"type": "String",
"required": true
}
}
}
}
Name | Type | Description |
---|---|---|
options |
String or Object
|
Boot options; If String, this is the application root directory; if object, has below properties. |
Name | Type | Description |
---|---|---|
appRootDir |
String
|
Directory to use when loading JSON and JavaScript files (optional). Defaults to the current directory ( |
models |
Object
|
Object containing |
dataSources |
Object
|
Object containing |
Define a DataSource.
Name | Type | Description |
---|---|---|
name |
String
|
The data source name |
config |
Object
|
The data source config |
Enable swagger REST API documentation.
Note: This method is deprecated. Use loopback-explorer instead.
Options
basePath
The basepath for your API - eg. 'http://localhost:3000'.Example
// enable docs
app.docs({basePath: 'http://localhost:3000'});
Run your app then navigate to the API explorer. Enter your API basepath to view your generated docs.
Enable app wide authentication.
Listen for connections and update the configured port.
When there are no parameters or there is only one callback parameter,
the server will listen on app.get('host')
and app.get('port')
.
// listen on host/port configured in app config
app.listen();
Otherwise all arguments are forwarded to http.Server.listen
.
// listen on the specified port and all hosts, ignore app config
app.listen(80);
The function also installs a listening
callback that calls
app.set('port')
with the value returned by server.address().port
.
This way the port param contains always the real port number, even when
listen was called with port number 0.
Name | Type | Description |
---|---|---|
cb |
Function
|
If specified, the callback is added as a listener for the server's "listening" event. |
Name | Type | Description |
---|---|---|
result |
http.Server
|
A node |
Define and attach a model to the app. The Model
will be available on the
app.models
object.
var Widget = app.model('Widget', {dataSource: 'db'});
Widget.create({name: 'pencil'});
app.models.Widget.find(function(err, widgets) {
console.log(widgets[0]); // => {name: 'pencil'}
});
Name | Type | Description |
---|---|---|
modelName |
String
|
The name of the model to define. |
config |
Object
|
The model's configuration. |
Name | Type | Description |
---|---|---|
dataSource |
String or DataSource
|
The |
[options] |
Object
|
an object containing |
[options.acls] |
Array.<ACL>
|
an array of |
[options.hidden] |
Array.<String>
|
experimental an array of properties to hide when accessed remotely. |
[properties] |
Object
|
object defining the |
Name | Type | Description |
---|---|---|
result |
ModelConstructor
|
the model class |
Get the models exported by the app. Returns only models defined using app.model()
There are two ways to access models:
app.models()
to get a list of all models.var models = app.models();
models.forEach(function (Model) {
console.log(Model.modelName); // color
});
**2. Use app.model
to access a model by name.
app.model
has properties for all defined models.
The following example illustrates accessing the Product
and CustomerReceipt
models
using the models
object.
var loopback = require('loopback');
var app = loopback();
app.boot({
dataSources: {
db: {connector: 'memory'}
}
});
app.model('product', {dataSource: 'db'});
app.model('customer-receipt', {dataSource: 'db'});
// available based on the given name
var Product = app.models.Product;
// also available as camelCase
var product = app.models.product;
// multi-word models are avaiable as pascal cased
var CustomerReceipt = app.models.CustomerReceipt;
// also available as camelCase
var customerReceipt = app.models.customerReceipt;
Name | Type | Description |
---|---|---|
result |
Array
|
Array of model classes. |
Get all remote objects.
Name | Type | Description |
---|---|---|
result |
Object
|
Lazily load a set of remote objects.
NOTE: Calling app.remotes()
more than once returns only a single set of remote objects.
Name | Type | Description |
---|---|---|
result |
RemoteObjects
|
Main entry for LoopBack core module. It provides static properties and
methods to create models and data sources. The module itself is a function
that creates loopback app
. For example,
var loopback = require('loopback');
var app = loopback();
Attach any model that does not have a dataSource to the default dataSource for the type the Model requests
Create a data source with passing the provided options to the connector.
Name | Type | Description |
---|---|---|
name |
String
|
Optional name. |
Data |
Object
|
Source options |
Name | Type | Description |
---|---|---|
connector |
Object
|
LoopBack connector. |
Other properties |
|
See the relevant connector documentation. |
Create a named vanilla JavaScript class constructor with an attached set of properties and options.
Name | Type | Description |
---|---|---|
name |
String
|
Unique name. |
properties |
Object
|
|
options |
Object
|
(optional) |
Get the default dataSource
for a given type
.
Name | Type | Description |
---|---|---|
type |
String
|
The datasource type |
Name | Type | Description |
---|---|---|
result |
DataSource
|
The data source instance |
Look up a model class by name from all models created by loopback.createModel()
Name | Type | Description |
---|---|---|
modelName |
String
|
The model name |
Name | Type | Description |
---|---|---|
result |
Model
|
The model class |
Look up a model class by the base model class. The method can be used by LoopBack to find configured models in models.json over the base model.
Name | Type | Description |
---|---|---|
The |
Model
|
base model class |
Name | Type | Description |
---|---|---|
result |
Model
|
The subclass if found or the base class |
Get an in-memory data source. Use one if it already exists.
Name | Type | Description |
---|---|---|
[name] |
String
|
The name of the data source. If not provided, the |
Add a remote method to a model.
Name | Type | Description |
---|---|---|
fn |
Function
|
|
options |
Object
|
(optional) |
Set the default dataSource
for a given type
.
Name | Type | Description |
---|---|---|
type |
String
|
The datasource type |
dataSource |
Object or DataSource
|
The data source settings or instance |
Name | Type | Description |
---|---|---|
result |
DataSource
|
The data source instance |
Create a template helper.
var render = loopback.template('foo.ejs');
var html = render({foo: 'bar'});
Name | Type | Description |
---|---|---|
path |
String
|
Path to the template file. |
Name | Type | Description |
---|---|---|
result |
Function
|
Options
cookies
- An Array
of cookie namesheaders
- An Array
of header namesparams
- An Array
of param namesmodel
- Specify an AccessToken class to useEach array is used to add additional keys to find an accessToken
for a request
.
The following example illustrates how to check for an accessToken
in a custom cookie, query string parameter
and header called foo-auth
.
app.use(loopback.token({
cookies: ['foo-auth'],
headers: ['foo-auth', 'X-Foo-Auth'],
cookies: ['foo-auth', 'foo_auth']
}));
Defaults
By default the following names will be checked. These names are appended to any optional names. They will always be checked, but any names specified will be checked first.
NOTE: The loopback.token()
middleware will only check for signed cookies.
Token based authentication and access control.
Name | Type | Description |
---|---|---|
id |
|
{String} Generated token ID |
ttl |
|
{Number} Time to live |
created |
|
{Date} When the token was created Default ACLs
|
Create a cryptographically random access token id.
Name | Type | Description |
---|---|---|
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
|
token |
String
|
Find a token for the given ServerRequest
.
Name | Type | Description |
---|---|---|
req |
ServerRequest
|
|
[options] |
Object
|
Options for finding the token |
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
|
token |
AccessToken
|
Validate the token.
Name | Type | Description |
---|---|---|
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
|
isValid |
Boolean
|
Access context represents the context for a request to access protected resources
Name | Type | Description |
---|---|---|
context |
Object
|
The context object |
Name | Type | Description |
---|---|---|
principals |
Array.<Principal>
|
An array of principals |
model |
Function
|
The model class |
modelName |
String
|
The model name |
modelId |
String
|
The model id |
property |
String
|
The model property/method/relation name |
method |
String
|
The model method to be invoked |
accessType |
String
|
The access type |
accessToken |
AccessToken
|
The access token |
Name | Type | Description |
---|---|---|
result |
AccessContext
|
Add a principal to the context
Name | Type | Description |
---|---|---|
principalType |
String
|
The principal type |
principalId |
|
The principal id |
[principalName] |
String
|
The principal name |
Name | Type | Description |
---|---|---|
result |
boolean
|
Print debug info for access context.
Get the application id
Name | Type | Description |
---|---|---|
result |
|
Get the user id
Name | Type | Description |
---|---|---|
result |
|
Check if the access context has authenticated principals
Name | Type | Description |
---|---|---|
result |
boolean
|
A request to access protected resources.
Name | Type | Description |
---|---|---|
model |
String
|
The model name |
property |
String
|
|
accessType |
String
|
The access type |
permission |
String
|
The requested permission |
Name | Type | Description |
---|---|---|
result |
AccessRequest
|
Is the request a wildcard
Name | Type | Description |
---|---|---|
result |
boolean
|
This class represents the abstract notion of a principal, which can be used to represent any entity, such as an individual, a corporation, and a login id
Name | Type | Description |
---|---|---|
type |
String
|
The principal type |
id |
|
The princiapl id |
[name] |
String
|
The principal name |
Name | Type | Description |
---|---|---|
result |
Principal
|
Compare if two principals are equal Returns true if argument principal is equal to this principal.
Name | Type | Description |
---|---|---|
principal |
Object
|
The other principal |
Name of the access type - READ/WRITE/EXEC
ALARM - Generate an alarm, in a system dependent way, the access specified in the permissions component of the ACL entry. ALLOW - Explicitly grants access to the resource. AUDIT - Log, in a system dependent way, the access specified in the permissions component of the ACL entry. DENY - Explicitly denies access to the resource.
Type of the principal - Application/User/Role
Id of the principal - such as appId, userId or roleId
A Model for access control meta data.
Check if the request has the permission to access
Name | Type | Description |
---|---|---|
context |
Object
|
|
callback |
Function
|
Name | Type | Description |
---|---|---|
principals |
Array.<Object>
|
An array of principals |
model |
String or Model
|
The model name or model class |
id |
|
The model instance id |
property |
String
|
The property/method/relation name |
accessType |
String
|
The access type |
Check if the given access token can invoke the method
Name | Type | Description |
---|---|---|
token |
AccessToken
|
The access token |
model |
String
|
The model name |
modelId |
|
The model id |
method |
String
|
The method name |
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
String or Error
|
The error object |
allowed |
Boolean
|
is the request allowed |
Check if the given principal is allowed to access the model/property
Name | Type | Description |
---|---|---|
principalType |
String
|
The principal type |
principalId |
String
|
The principal id |
model |
String
|
The model name |
property |
String
|
The property/method/relation name |
accessType |
String
|
The access type |
callback |
Function
|
The callback function |
callback
|
Name | Type | Description |
---|---|---|
err |
String or Error
|
The error object |
result |
AccessRequest
|
The access permission |
Calculate the matching score for the given rule and request
Name | Type | Description |
---|---|---|
rule |
ACL
|
The ACL entry |
req |
AccessRequest
|
The request |
Name | Type | Description |
---|---|---|
result |
number
|
Resource owner grants/delegates permissions to client applications
For a protected resource, does the client application have the authorization from the resource owner (user or system)?
Scope has many resource access entries
Check if the given scope is allowed to access the model/property
Name | Type | Description |
---|---|---|
scope |
String
|
The scope name |
model |
String
|
The model name |
property |
String
|
The property/method/relation name |
accessType |
String
|
The access type |
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
String or Error
|
The error object |
result |
AccessRequest
|
The access permission |
production or development mode. It denotes what default APNS servers to be used to send notifications
Manage client applications and organize their users.
Authenticate the application id and key.
matched
parameter is one of:
Name | Type | Description |
---|---|---|
appId |
Any
|
|
key |
String
|
|
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
|
matched |
String
|
The matching key |
Register a new application
Name | Type | Description |
---|---|---|
owner |
|
Owner's user id |
name |
|
Name of the application |
options |
|
Other options |
cb |
|
Callback function |
Reset keys for a given application by the appId
Name | Type | Description |
---|---|---|
appId |
Any
|
|
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
Reset keys for the application instance
Name | Type | Description |
---|---|---|
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
The Email Model.
Properties
to
- String (required)from
- String (required)subject
- String (required)text
- Stringhtml
- StringSend an email with the given options
.
Example Options:
{
from: "Fred Foo <foo@blurdybloop.com>", // sender address
to: "bar@blurdybloop.com, baz@blurdybloop.com", // list of receivers
subject: "Hello", // Subject line
text: "Hello world", // plaintext body
html: "<b>Hello world</b>" // html body
}
See https://github.com/andris9/Nodemailer for other supported options.
Name | Type | Description |
---|---|---|
options |
Object
|
See below |
callback |
Function
|
Called after the e-mail is sent or the sending failed |
Name | Type | Description |
---|---|---|
from |
String
|
Senders's email address |
to |
String
|
List of one or more recipient email addresses (comma-delimited) |
subject |
String
|
Subject line |
text |
String
|
Body text |
html |
String
|
Body HTML (optional) |
The built in loopback.Model.
Name | Type | Description |
---|---|---|
data |
Object
|
Check if the given access token can invoke the method
Name | Type | Description |
---|---|---|
token |
AccessToken
|
The access token |
modelId |
|
The model id |
method |
String
|
The method name |
callback |
|
The callback function |
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
String or Error
|
The error object |
allowed |
Boolean
|
is the request allowed |
Get the Application
the Model is attached to.
Name | Type | Description |
---|---|---|
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
|
app |
Application
|
Get the Model's RemoteObjects
.
Name | Type | Description |
---|---|---|
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
|
remoteObjects |
RemoteObjects
|
Extends Model with basic query and CRUD support.
Change Event
Listen for model changes using the change
event.
MyDataModel.on('changed', function(obj) {
console.log(obj) // => the changed model
});
Name | Type | Description |
---|---|---|
data |
Object
|
|
data.id |
Number
|
The default id property |
Return count of matched records
Name | Type | Description |
---|---|---|
where |
Object
|
search conditions (optional) |
cb |
Function
|
callback, called with (err, count) |
Create new instance of Model class, saved in database
Name | Type | Description |
---|---|---|
data |
|
[optional] |
callback(err, |
|
obj) callback called with arguments:
|
Check whether a model instance exists in database
Name | Type | Description |
---|---|---|
id |
id
|
identifier of object (primary key value) |
cb |
Function
|
callbacl called with (err, exists: Bool) |
Find all instances of Model, matched by query
make sure you have marked as index: true
fields for filter or sort
Name | Type | Description |
---|---|---|
params |
Object
|
(optional)
|
callback |
Function
|
(required) called with arguments:
|
Find object by id
Name | Type | Description |
---|---|---|
id |
|
primary key value |
cb |
Function
|
callback called with (err, instance) |
Find one record, same as all
, limited by 1 and return object, not collection
Name | Type | Description |
---|---|---|
params |
Object
|
search conditions: {where: {test: 'me'}} |
cb |
Function
|
callback called with (err, instance) |
Find one record, same as all
, limited by 1 and return object, not collection,
if not found, create using data provided as second argument
Name | Type | Description |
---|---|---|
query |
Object
|
search conditions: {where: {test: 'me'}}. |
data |
Object
|
object to create. |
cb |
Function
|
callback called with (err, instance) |
Get the id property name
Destroy all matching records
Name | Type | Description |
---|---|---|
[where] |
Object
|
An object that defines the criteria |
[cb] |
Function
|
callback called with (err) |
Destroy a record by id
Name | Type | Description |
---|---|---|
id |
|
The id value |
cb |
Function
|
callback called with (err) |
Update or insert a model instance
Name | Type | Description |
---|---|---|
data |
Object
|
The model instance data |
[callback] |
Function
|
The callback function |
Get the id property name of the constructor.
Determine if the data model is new.
Name | Type | Description |
---|---|---|
result |
Boolean
|
Reload object from persistence
Name | Type | Description |
---|---|---|
callback |
Function
|
called with (err, instance) arguments |
Save instance. When instance haven't id, create method called instead. Triggers: validate, save, update | create
Name | Type | Description |
---|---|---|
options |
|
{validate: true, throws: false} [optional] |
callback(err, |
|
obj) |
Set the corret id
property for the DataModel
. If a Connector
defines
a setId
method it will be used. Otherwise the default lookup is used. You
should override this method to handle complex ids.
Name | Type | Description |
---|---|---|
val |
|
The |
Update single attribute
equals to `updateAttributes({name: value}, cb)
Name | Type | Description |
---|---|---|
name |
String
|
name of property |
value |
Mixed
|
value of property |
callback |
Function
|
callback called with (err, instance) |
Update set of attributes
this method performs validation before updating
Name | Type | Description |
---|---|---|
data |
Object
|
data to update |
callback |
Function
|
callback called with (err, instance) |
The Role Model
List roles for a given principal
Name | Type | Description |
---|---|---|
context |
Object
|
The security context |
callback |
Function
|
|
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
|
|
An |
Array.<String>
|
array of role ids |
Check if the user id is authenticated
Name | Type | Description |
---|---|---|
context |
Object
|
The security context |
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
|
isAuthenticated |
Boolean
|
Check if a given principal is in the role
Name | Type | Description |
---|---|---|
role |
String
|
The role name |
context |
Object
|
The context object |
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
|
isInRole |
Boolean
|
Check if a given userId is the owner the model instance
Name | Type | Description |
---|---|---|
modelClass |
Function
|
The model class |
modelId |
|
The model id |
{*) userId The user id |
|
|
callback |
Function
|
Add custom handler for roles
Name | Type | Description |
---|---|---|
role |
|
|
resolver |
|
The resolver function decides if a principal is in the role dynamically function(role, context, callback) |
The RoleMapping
model extends from the built in loopback.Model
type.
Get the application principal
Name | Type | Description |
---|---|---|
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
|
application |
Application
|
Get the child role principal
Name | Type | Description |
---|---|---|
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
|
childUser |
User
|
Get the user principal
Name | Type | Description |
---|---|---|
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
|
user |
User
|
factors: [ 'AuthenticationFactor' ],
Extends from the built in loopback.Model
type.
Default User
ACLs.
*
create
removeById
login
logout
findById
updateAttributes
Confirm the user's identity.
Name | Type | Description |
---|---|---|
userId |
Any
|
|
token |
String
|
The validation token |
redirect |
String
|
URL to redirect the user to once confirmed |
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
Login a user by with the given credentials
.
User.login({username: 'foo', password: 'bar'}, function (err, token) {
console.log(token.id);
});
Name | Type | Description |
---|---|---|
credentials |
Object
|
|
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
|
token |
AccessToken
|
Logout a user with the given accessToken id.
User.logout('asd0a9f8dsj9s0s3223mk', function (err) {
console.log(err || 'Logged out');
});
Name | Type | Description |
---|---|---|
accessTokenID |
String
|
|
callback |
Function
|
Name | Type | Description |
---|---|---|
err |
Error
|
Create a short lived acess token for temporary login. Allows users to change passwords if forgotten.
Name | Type | Description |
---|---|---|
options |
Object
|
|
callback |
Function
|
Name | Type | Description |
---|---|---|
String
|
The user's email address |
Name | Type | Description |
---|---|---|
err |
Error
|
Compare the given password
with the users hashed password.
Name | Type | Description |
---|---|---|
password |
String
|
The plain text password |
Name | Type | Description |
---|---|---|
result |
Boolean
|
Verify a user's identity by sending them a confirmation email.
var options = {
type: 'email',
to: user.email,
template: 'verify.ejs',
redirect: '/'
};
user.verify(options, next);
Name | Type | Description |
---|---|---|
options |
Object
|
A Loopback Model
is a vanilla JavaScript class constructor with an attached set of properties and options. A Model
instance is created by passing a data object containing properties to the Model
constructor. A Model
constructor will clean the object passed to it and only set the values matching the properties you define.
// valid color
var Color = loopback.createModel('color', {name: String});
var red = new Color({name: 'red'});
console.log(red.name); // red
// invalid color
var foo = new Color({bar: 'bat baz'});
console.log(foo.bar); // undefined
Properties
A model defines a list of property names, types and other validation metadata. A DataSource uses this definition to validate a Model
during operations such as save()
.
Options
Some DataSources may support additional Model
options.
Define A Loopbackmodel.
var User = loopback.createModel('user', {
first: String,
last: String,
age: Number
});
Attach a model to a DataSource. Attaching a DataSource updates the model with additional methods and behaviors.
var oracle = loopback.createDataSource({
connector: require('loopback-connector-oracle'),
host: '111.22.333.44',
database: 'MYDB',
username: 'username',
password: 'password'
});
User.attachTo(oracle);
NOTE: until a model is attached to a data source it will not have any attached methods.
An object containing a normalized set of properties supplied to loopback.createModel(name, properties)
.
Example:
var props = {
a: String,
b: {type: 'Number'},
c: {type: 'String', min: 10, max: 100},
d: Date,
e: loopback.GeoPoint
};
var MyModel = loopback.createModel('foo', props);
console.log(MyModel.properties);
Outputs:
{
"a": {type: String},
"b": {type: Number},
"c": {
"type": String,
"min": 10,
"max": 100
},
"d": {type: Date},
"e": {type: GeoPoint},
"id": {
"id": 1
}
}
Mixins are added by attaching a vanilla model to a data source with a connector. Each connector enables its own set of operations that are mixed into a Model
as methods. To see available methods for a data source call dataSource.operations()
.
Log the available methods for a memory data source.
var ops = loopback
.createDataSource({connector: loopback.Memory})
.operations();
console.log(Object.keys(ops));
Outputs:
[ 'create',
'updateOrCreate',
'upsert',
'findOrCreate',
'exists',
'findById',
'find',
'all',
'findOne',
'destroyAll',
'deleteAll',
'count',
'include',
'relationNameFor',
'hasMany',
'belongsTo',
'hasAndBelongsToMany',
'save',
'isNewRecord',
'destroy',
'delete',
'updateAttribute',
'updateAttributes',
'reload' ]
Here is the definition of the count()
operation.
{
accepts: [ { arg: 'where', type: 'object' } ],
http: { verb: 'get', path: '/count' },
remoteEnabled: true,
name: 'count'
}
Note: These are the default mixin methods for a Model
attached to a data source. See the specific connector for additional API documentation.
Create an instance of Model with given data and save to the attached data source. Callback is optional.
User.create({first: 'Joe', last: 'Bob'}, function(err, user) {
console.log(user instanceof User); // true
});
Note: You must include a callback and use the created model provided in the callback if your code depends on your model being saved or having an id
.
Query count of Model instances in data source. Optional query param allows to count filtered set of Model instances.
User.count({approved: true}, function(err, count) {
console.log(count); // 2081
});
Find all instances of Model, matched by query. Fields used for filter and sort should be declared with {index: true}
in model definition.
filter
where Object
{ key: val, key2: {gt: 'val2'}} The search criteria
include String
, Object
or Array
Allows you to load relations of several objects and optimize numbers of requests.
order String
The sorting order
limit Number
The maximum number of instances to be returned
skip Number
Skip the number of instances
offset Number
Alias for skip
fields Object|Array|String
The included/excluded fields
['foo']
or 'foo'
- include only the foo property['foo', 'bar']
- include the foo and bar properties{foo: true}
- include only foo{bat: false}
- include all properties, exclude batFind the second page of 10 users over age 21 in descending order exluding the password property.
User.find({
where: {
age: {gt: 21}},
order: 'age DESC',
limit: 10,
skip: 10,
fields: {password: false}
},
console.log
);
Note: See the specific connector's docs for more info.
Delete all Model instances from data source. Note: destroyAll method does not perform destroy hooks.
Product.destroyAll({price: {gt: 99}}, function(err) {
// removed matching products
});
*NOTE:
where
is optional and a where object... do NOT pass a filter object
Find instance by id.
User.findById(23, function(err, user) {
console.info(user.id); // 23
});
Find a single instance that matches the given where expression.
User.findOne({where: {id: 23}}, function(err, user) {
console.info(user.id); // 23
});
Update when record with id=data.id found, insert otherwise. Note: no setters, validations or hooks applied when using upsert.
Define a static model method.
User.login = function (username, password, fn) {
var passwordHash = hashPassword(password);
this.findOne({username: username}, function (err, user) {
var failErr = new Error('login failed');
if(err) {
fn(err);
} else if(!user) {
fn(failErr);
} else if(user.password === passwordHash) {
MyAccessTokenModel.create({userId: user.id}, function (err, accessToken) {
fn(null, accessToken.id);
});
} else {
fn(failErr);
}
});
}
Setup the static model method to be exposed to clients as a remote method.
loopback.remoteMethod(
User.login,
{
accepts: [
{arg: 'username', type: 'string', required: true},
{arg: 'password', type: 'string', required: true}
],
returns: {arg: 'sessionId', type: 'any'},
http: {path: '/sign-in'}
}
);
Note: These are the default mixin methods for a Model
attached to a data source. See the specific connector for additional API documentation.
Save an instance of a Model to the attached data source.
var joe = new User({first: 'Joe', last: 'Bob'});
joe.save(function(err, user) {
if(user.errors) {
console.log(user.errors);
} else {
console.log(user.id);
}
});
Save specified attributes to the attached data source.
user.updateAttributes({
first: 'updatedFirst',
name: 'updatedLast'
}, fn);
Remove a model from the attached data source.
model.destroy(function(err) {
// model instance destroyed
});
Define an instance method.
User.prototype.logout = function (fn) {
MySessionModel.destroyAll({userId: this.id}, fn);
}
Define a remote model instance method.
loopback.remoteMethod(User.prototype.logout)
Define a "one to many" relationship.
// by referencing model
Book.hasMany(Chapter);
// specify the name
Book.hasMany('chapters', {model: Chapter});
Query and create the related models.
Book.create(function(err, book) {
// create a chapter instance
// ready to be saved in the data source
var chapter = book.chapters.build({name: 'Chapter 1'});
// save the new chapter
chapter.save();
// you can also call the Chapter.create method with
// the `chapters` property which will build a chapter
// instance and save the it in the data source
book.chapters.create({name: 'Chapter 2'}, function(err, savedChapter) {
// this callback is optional
});
// query chapters for the book using the
book.chapters(function(err, chapters) {
// all chapters with bookId = book.id
console.log(chapters);
});
book.chapters({where: {name: 'test'}, function(err, chapters) {
// all chapters with bookId = book.id and name = 'test'
console.log(chapters);
});
});
A belongsTo
relation sets up a one-to-one connection with another model, such
that each instance of the declaring model "belongs to" one instance of the other
model. For example, if your application includes users and posts, and each post
can be written by exactly one user.
Post.belongsTo(User, {as: 'author', foreignKey: 'userId'});
The code above basically says Post has a reference called author
to User using
the userId
property of Post as the foreign key. Now we can access the author
in one of the following styles:
post.author(callback); // Get the User object for the post author asynchronously
post.author(); // Get the User object for the post author synchronously
post.author(user) // Set the author to be the given user
A hasAndBelongsToMany
relation creates a direct many-to-many connection with
another model, with no intervening model. For example, if your application
includes users and groups, with each group having many users and each user
appearing in many groups, you could declare the models this way,
User.hasAndBelongsToMany('groups', {model: Group, foreignKey: 'groupId'});
user.groups(callback); // get groups of the user
user.groups.create(data, callback); // create a new group and connect it with the user
user.groups.add(group, callback); // connect an existing group with the user
user.groups.remove(group, callback); // remove the user from the group
Any static or instance method can be decorated as shared
. These methods are exposed over the provided transport (eg. loopback.rest).
You can expose a Model's instance and static methods to clients. A remote method must accept a callback with the conventional fn(err, result, ...)
signature.
Expose a remote method.
Product.stats = function(fn) {
var statsResult = {
totalPurchased: 123456
};
var err = null;
// callback with an error and the result
fn(err, statsResult);
}
loopback.remoteMethod(
Product.stats,
{
returns: {arg: 'stats', type: 'object'},
http: {path: '/info', verb: 'get'}
}
);
Options
The options argument is a JSON object, described in the following table.
Option | Required? | Description |
---|---|---|
accepts | No | Describes the remote method's arguments; See Argument description. The callback argument is assumed; do not specify. |
returns | No | Describes the remote method's callback arguments; See Argument description. The err argument is assumed; do not specify. |
http | No | HTTP routing information:
|
description | No | A text description of the method. This is used by API documentation generators like Swagger. |
The arguments description defines either a single argument as an object or an ordered set of arguments as an array. Each individual argument has keys for:
true
if your function
has a single callback argument to use as the root object
returned to remote caller. Otherwise the root object returned is a map (argument-name to argument-value).For example, a single argument, specified as an object:
{arg: 'myArg', type: 'number'}
Multiple arguments, specified as an array:
[
{arg: 'arg1', type: 'number', required: true},
{arg: 'arg2', type: 'array'}
]
HTTP mapping of input arguments
There are two ways to specify HTTP mapping for input parameters (what the method accepts):
source
propertyTo use the first way to specify HTTP mapping for input parameters, provide an object with a source
property
that has one of the values shown in the following table.
Value of source property | Description |
---|---|
body | The whole request body is used as the value. |
form | The value is looked up using req.param , which searches route arguments, the request body and the query string. |
query | An alias for form (see above). |
path | An alias for form (see above). |
req | The whole HTTP reqest object is used as the value. |
For example, an argument getting the whole request body as the value:
{ arg: 'data', type: 'object', http: { source: 'body' } }
The use the second way to specify HTTP mapping for input parameters, specify a custom mapping function that looks like this:
{
arg: 'custom',
type: 'number',
http: function(ctx) {
// ctx is LoopBack Context object
// 1. Get the HTTP request object as provided by Express
var req = ctx.req;
// 2. Get 'a' and 'b' from query string or form data
// and return their sum as the value
return +req.param('a') + req.param('b');
}
}
If you don't specify a mapping, LoopBack will determine the value
as follows (assuming name
as the name of the input parameter to resolve):
args
with a JSON content,
then the value of args['name']
is used if it is defined.req.param('name')
is returned.Run a function before or after a remote method is called by a client.
// *.save === prototype.save
User.beforeRemote('*.save', function(ctx, user, next) {
if(ctx.user) {
next();
} else {
next(new Error('must be logged in to update'))
}
});
User.afterRemote('*.save', function(ctx, user, next) {
console.log('user has been saved', user);
next();
});
Remote hooks also support wildcards. Run a function before any remote method is called.
// ** will match both prototype.* and *.*
User.beforeRemote('**', function(ctx, user, next) {
console.log(ctx.methodString, 'was invoked remotely'); // users.prototype.save was invoked remotely
next();
});
Other wildcard examples
// run before any static method eg. User.find
User.beforeRemote('*', ...);
// run before any instance method eg. User.prototype.save
User.beforeRemote('prototype.*', ...);
// prevent password hashes from being sent to clients
User.afterRemote('**', function (ctx, user, next) {
if(ctx.result) {
if(Array.isArray(ctx.result)) {
ctx.result.forEach(function (result) {
result.password = undefined;
});
} else {
ctx.result.password = undefined;
}
}
next();
});
Remote hooks are provided with a Context ctx
object which contains transport specific data (eg. for http: req
and res
). The ctx
object also has a set of consistent apis across transports.
The accessToken
of the user calling the method remotely. Note: this is undefined if the remote method is not invoked by a logged in user (or other principal).
During afterRemote
hooks, ctx.result
will contain the data about to be sent to a client. Modify this object to transform data before it is sent.
When loopback.rest is used the following additional ctx
properties are available.
The express ServerRequest object. See full documentation.
The express ServerResponse object. See full documentation.