Merge pull request #13 from strongloop/doc_edits

API Doc Style / Formatting
This commit is contained in:
Ritchie Martori 2013-08-27 08:44:04 -07:00
commit 989e9f398c
6 changed files with 621 additions and 482 deletions

View File

@ -6,6 +6,7 @@
"docs/gettingstarted.md", "docs/gettingstarted.md",
"docs/resources.md", "docs/resources.md",
"docs/concepts.md", "docs/concepts.md",
{"title": "API", "depth": 2},
"docs/api.md", "docs/api.md",
"docs/rest.md" "docs/rest.md"
] ]

View File

@ -1,9 +1,10 @@
## API ## Node.js API
### App ### App
Create a Loopback application. Create a Loopback application.
```js
var loopback = require('loopback'); var loopback = require('loopback');
var app = loopback(); var app = loopback();
@ -12,17 +13,19 @@ Create a Loopback application.
}); });
app.listen(3000); app.listen(3000);
```
**Notes:** > **Notes**
>
- extends [express](http://expressjs.com/api.html#express) > - extends [express](http://expressjs.com/api.html#express)
- see [express docs](http://expressjs.com/api.html) for details > - see [express docs](http://expressjs.com/api.html) for details
- supports [express / connect middleware](http://expressjs.com/api.html#middleware) > - supports [express / connect middleware](http://expressjs.com/api.html#middleware)
#### app.model(Model) #### app.model(Model)
Expose a `Model` to remote clients. Expose a `Model` to remote clients.
```js
// create a testing data source // create a testing data source
var memory = loopback.memory(); var memory = loopback.memory();
var Color = memory.createModel('color', {name: String}); var Color = memory.createModel('color', {name: String});
@ -30,18 +33,21 @@ Expose a `Model` to remote clients.
app.model(Color); app.model(Color);
app.use(loopback.rest()); app.use(loopback.rest());
```
**Note:** this will expose all [shared methods](#shared-methods) on the model. > **Note** - this will expose all [shared methods](#shared-methods) on the model.
#### app.models() #### app.models()
Get the app's exposed models. Get the app's exposed models.
```js
var models = app.models(); var models = app.models();
models.forEach(function (Model) { models.forEach(function (Model) {
console.log(Model.modelName); // color console.log(Model.modelName); // color
}); });
```
#### app.docs(options) #### app.docs(options)
@ -53,8 +59,10 @@ Enable swagger REST api documentation.
**Example** **Example**
```js
// enable docs // enable docs
app.docs({basePath: 'http://localhost:3000'}); app.docs({basePath: 'http://localhost:3000'});
```
Run your app then navigate to [the api explorer](http://petstore.swagger.wordnik.com/). Enter your API basepath to view your generated docs. Run your app then navigate to [the api explorer](http://petstore.swagger.wordnik.com/). Enter your API basepath to view your generated docs.
@ -62,6 +70,7 @@ Run your app then navigate to [the api explorer](http://petstore.swagger.wordnik
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. 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.
```js
// valid color // valid color
var Color = loopback.createModel('color', {name: String}); var Color = loopback.createModel('color', {name: String});
var red = new Color({name: 'red'}); var red = new Color({name: 'red'});
@ -70,6 +79,7 @@ A Loopback `Model` is a vanilla JavaScript class constructor with an attached se
// invalid color // invalid color
var foo = new Color({bar: 'bat baz'}); var foo = new Color({bar: 'bat baz'});
console.log(foo.bar); // undefined console.log(foo.bar); // undefined
```
**Properties** **Properties**
@ -81,55 +91,71 @@ Some [DataSources](#data-source) may support additional `Model` options.
Define A Loopbackmodel. Define A Loopbackmodel.
```js
var User = loopback.createModel('user', { var User = loopback.createModel('user', {
first: String, first: String,
last: String, last: String,
age: Number age: Number
}); });
```
### Validation (expiremental) #### Validation (expiremental)
#### Model.validatesFormatOf(property, options) ##### Model.validatesFormatOf(property, options)
Require a model to include a property that matches the given format. Require a model to include a property that matches the given format.
```js
User.validatesFormat('name', {with: /\w+/}); User.validatesFormat('name', {with: /\w+/});
```
#### Model.validatesPresenceOf(properties...) ##### Model.validatesPresenceOf(properties...)
Require a model to include a property to be considered valid. Require a model to include a property to be considered valid.
```js
User.validatesPresenceOf('first', 'last', 'age'); User.validatesPresenceOf('first', 'last', 'age');
```
#### Model.validatesLengthOf(property, options) ##### Model.validatesLengthOf(property, options)
Require a property length to be within a specified range. Require a property length to be within a specified range.
```js
User.validatesLengthOf('password', {min: 5, message: {min: 'Password is too short'}}); User.validatesLengthOf('password', {min: 5, message: {min: 'Password is too short'}});
```
#### Model.validatesInclusionOf(property, options) ##### Model.validatesInclusionOf(property, options)
Require a value for `property` to be in the specified array. Require a value for `property` to be in the specified array.
```js
User.validatesInclusionOf('gender', {in: ['male', 'female']}); User.validatesInclusionOf('gender', {in: ['male', 'female']});
```
#### Model.validatesExclusionOf(property, options) ##### Model.validatesExclusionOf(property, options)
Require a value for `property` to not exist in the specified array. Require a value for `property` to not exist in the specified array.
```js
User.validatesExclusionOf('domain', {in: ['www', 'billing', 'admin']}); User.validatesExclusionOf('domain', {in: ['www', 'billing', 'admin']});
```
#### Model.validatesNumericalityOf(property, options) ##### Model.validatesNumericalityOf(property, options)
Require a value for `property` to be a specific type of `Number`. Require a value for `property` to be a specific type of `Number`.
```js
User.validatesNumericalityOf('age', {int: true}); User.validatesNumericalityOf('age', {int: true});
```
#### Model.validatesUniquenessOf(property, options) ##### Model.validatesUniquenessOf(property, options)
Ensure the value for `property` is unique in the collection of models. Ensure the value for `property` is unique in the collection of models.
```js
User.validatesUniquenessOf('email', {message: 'email is not unique'}); User.validatesUniquenessOf('email', {message: 'email is not unique'});
```
**Note:** not available for all [connectors](#connectors). **Note:** not available for all [connectors](#connectors).
@ -139,15 +165,22 @@ Currently supported in these connectors:
- [Oracle](http://github.com/strongloop/loopback-connector-oracle) - [Oracle](http://github.com/strongloop/loopback-connector-oracle)
- [MongoDB](http://github.com/strongloop/loopback-connector-mongodb) - [MongoDB](http://github.com/strongloop/loopback-connector-mongodb)
#### myModel.isValid() ##### myModel.isValid()
Validate the model instance. Validate the model instance.
```js
user.isValid(function (valid) { user.isValid(function (valid) {
if (!valid) { if (!valid) {
user.errors // hash of errors {attr: [errmessage, errmessage, ...], attr: ...} console.log(user.errors);
// => hash of errors
// => {
// => username: [errmessage, errmessage, ...],
// => email: ...
// => }
} }
}); });
```
#### Model.properties #### Model.properties
@ -155,6 +188,7 @@ An object containing a normalized set of properties supplied to `loopback.create
Example: Example:
```js
var props = { var props = {
a: String, a: String,
b: {type: 'Number'}, b: {type: 'Number'},
@ -166,9 +200,11 @@ Example:
var MyModel = loopback.createModel('foo', props); var MyModel = loopback.createModel('foo', props);
console.log(MyModel.properties); console.log(MyModel.properties);
```
Outputs: Outputs:
```js
{ {
"a": {type: String}, "a": {type: String},
"b": {type: Number}, "b": {type: Number},
@ -183,11 +219,13 @@ Outputs:
"id": 1 "id": 1
} }
} }
```
#### Model.attachTo(dataSource) #### Model.attachTo(dataSource)
Attach a model to a [DataSource](#data-source). Attaching a [DataSource](#data-source) updates the model with additional methods and behaviors. Attach a model to a [DataSource](#data-source). Attaching a [DataSource](#data-source) updates the model with additional methods and behaviors.
```js
var oracle = loopback.createDataSource({ var oracle = loopback.createDataSource({
connector: require('loopback-connector-oracle'), connector: require('loopback-connector-oracle'),
host: '111.22.333.44', host: '111.22.333.44',
@ -197,6 +235,7 @@ Attach a model to a [DataSource](#data-source). Attaching a [DataSource](#data-s
}); });
User.attachTo(oracle); User.attachTo(oracle);
```
**Note:** until a model is attached to a data source it will **not** have any **attached methods**. **Note:** until a model is attached to a data source it will **not** have any **attached methods**.
@ -206,14 +245,17 @@ Mixins are added by attaching a vanilla model to a [data source](#data-source) w
Log the available methods for a memory data source. Log the available methods for a memory data source.
```js
var ops = loopback var ops = loopback
.createDataSource({connector: loopback.Memory}) .createDataSource({connector: loopback.Memory})
.operations(); .operations();
console.log(Object.keys(ops)); console.log(Object.keys(ops));
```
Outputs: Outputs:
```js
[ 'create', [ 'create',
'updateOrCreate', 'updateOrCreate',
'upsert', 'upsert',
@ -238,15 +280,18 @@ Outputs:
'updateAttribute', 'updateAttribute',
'updateAttributes', 'updateAttributes',
'reload' ] 'reload' ]
```
Here is the definition of the `count()` operation. Here is the definition of the `count()` operation.
```js
{ {
accepts: [ { arg: 'where', type: 'object' } ], accepts: [ { arg: 'where', type: 'object' } ],
http: { verb: 'get', path: '/count' }, http: { verb: 'get', path: '/count' },
remoteEnabled: true, remoteEnabled: true,
name: 'count' name: 'count'
} }
```
#### Static Methods #### Static Methods
@ -256,9 +301,11 @@ Here is the definition of the `count()` operation.
Create an instance of Model with given data and save to the attached data source. Callback is optional. Create an instance of Model with given data and save to the attached data source. Callback is optional.
```js
User.create({first: 'Joe', last: 'Bob'}, function(err, user) { User.create({first: 'Joe', last: 'Bob'}, function(err, user) {
console.log(user instanceof User); // true 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`. **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`.
@ -266,9 +313,11 @@ Create an instance of Model with given data and save to the attached data source
Query count of Model instances in data source. Optional query param allows to count filtered set of Model instances. Query count of Model instances in data source. Optional query param allows to count filtered set of Model instances.
```js
User.count({approved: true}, function(err, count) { User.count({approved: true}, function(err, count) {
console.log(count); // 2081 console.log(count); // 2081
}); });
```
##### Model.find(filter, callback) ##### Model.find(filter, callback)
@ -289,6 +338,7 @@ Find all instances of Model, matched by query. Fields used for filter and sort s
Find the second page of 10 users over age 21 in descending order exluding the password property. Find the second page of 10 users over age 21 in descending order exluding the password property.
```js
User.find({ User.find({
where: { where: {
age: {gt: 21}}, age: {gt: 21}},
@ -299,6 +349,7 @@ Find the second page of 10 users over age 21 in descending order exluding the pa
}, },
console.log console.log
); );
```
**Note:** See the specific connector's [docs](#connectors) for more info. **Note:** See the specific connector's [docs](#connectors) for more info.
@ -310,17 +361,21 @@ Delete all Model instances from data source. **Note:** destroyAll method does no
Find instance by id. Find instance by id.
```js
User.findById(23, function(err, user) { User.findById(23, function(err, user) {
console.info(user.id); // 23 console.info(user.id); // 23
}); });
```
##### Model.findOne(where, callback) ##### Model.findOne(where, callback)
Find a single instance that matches the given where expression. Find a single instance that matches the given where expression.
```js
User.findOne({id: 23}, function(err, user) { User.findOne({id: 23}, function(err, user) {
console.info(user.id); // 23 console.info(user.id); // 23
}); });
```
##### Model.upsert(data, callback) ##### Model.upsert(data, callback)
@ -330,6 +385,7 @@ Update when record with id=data.id found, insert otherwise. **Note:** no setters
Define a static model method. Define a static model method.
```js
User.login = function (username, password, fn) { User.login = function (username, password, fn) {
var passwordHash = hashPassword(password); var passwordHash = hashPassword(password);
this.findOne({username: username}, function (err, user) { this.findOne({username: username}, function (err, user) {
@ -348,9 +404,11 @@ Define a static model method.
} }
}); });
} }
```
Setup the static model method to be exposed to clients as a [remote method](#remote-method). Setup the static model method to be exposed to clients as a [remote method](#remote-method).
```js
loopback.remoteMethod( loopback.remoteMethod(
User.login, User.login,
{ {
@ -362,6 +420,7 @@ Setup the static model method to be exposed to clients as a [remote method](#rem
http: {path: '/sign-in'} http: {path: '/sign-in'}
} }
); );
```
#### Instance Methods #### Instance Methods
@ -371,6 +430,7 @@ Setup the static model method to be exposed to clients as a [remote method](#rem
Save an instance of a Model to the attached data source. Save an instance of a Model to the attached data source.
```js
var joe = new User({first: 'Joe', last: 'Bob'}); var joe = new User({first: 'Joe', last: 'Bob'});
joe.save(function(err, user) { joe.save(function(err, user) {
if(user.errors) { if(user.errors) {
@ -379,44 +439,54 @@ Save an instance of a Model to the attached data source.
console.log(user.id); console.log(user.id);
} }
}); });
```
##### model.updateAttributes(data, [callback]) ##### model.updateAttributes(data, [callback])
Save specified attributes to the attached data source. Save specified attributes to the attached data source.
```js
user.updateAttributes({ user.updateAttributes({
first: 'updatedFirst', first: 'updatedFirst',
name: 'updatedLast' name: 'updatedLast'
}, fn); }, fn);
```
##### model.destroy([callback]) ##### model.destroy([callback])
Remove a model from the attached data source. Remove a model from the attached data source.
```js
model.destroy(function(err) { model.destroy(function(err) {
// model instance destroyed // model instance destroyed
}); });
```
##### Custom Instance Methods ##### Custom Instance Methods
Define an instance method. Define an instance method.
```js
User.prototype.logout = function (fn) { User.prototype.logout = function (fn) {
MySessionModel.destroyAll({userId: this.id}, fn); MySessionModel.destroyAll({userId: this.id}, fn);
} }
```
Define a remote model instance method. Define a remote model instance method.
loopback.remoteMethod(User.prototype.logout); ```js
loopback.remoteMethod(User.prototype.logout)
```
#### Remote Methods #### Remote Methods
Both instance and static methods can be exposed to clients. A remote method must accept a callback with the conventional `fn(err, result, ...)` signature. Both instance and static methods can be exposed to clients. A remote method must accept a callback with the conventional `fn(err, result, ...)` signature.
##### loopback.remoteMethod(fn, [options]); ##### loopback.remoteMethod(fn, [options])
Expose a remote method. Expose a remote method.
```js
Product.stats = function(fn) { Product.stats = function(fn) {
var calc = require('./stats'); var calc = require('./stats');
@ -433,10 +503,11 @@ Expose a remote method.
http: {path: '/info', verb: 'get'} http: {path: '/info', verb: 'get'}
} }
); );
```
**Options** **Options**
- **accepts** - (optional) an arguments description specifying the remote method's arguments. A - **accepts** - (optional) an arguments description specifying the remote method's arguments.
- **returns** - (optional) an arguments description specifying the remote methods callback arguments. - **returns** - (optional) an arguments description specifying the remote methods callback arguments.
- **http** - (advanced / optional, object) http routing info - **http** - (advanced / optional, object) http routing info
- **http.path** - the path relative to the model the method will be exposed at. May be a path fragment (eg. '/:myArg') which will be populated by an arg of the same name in the accepts description. For example the stats method above will be at the whole path `/products/stats`. - **http.path** - the path relative to the model the method will be exposed at. May be a path fragment (eg. '/:myArg') which will be populated by an arg of the same name in the accepts description. For example the stats method above will be at the whole path `/products/stats`.
@ -446,6 +517,7 @@ Expose a remote method.
An arguments description defines either a single argument as an object or an ordered set of arguments as an array. An arguments description defines either a single argument as an object or an ordered set of arguments as an array.
```js
// examples // examples
{arg: 'myArg', type: 'number'} {arg: 'myArg', type: 'number'}
@ -453,6 +525,7 @@ An arguments description defines either a single argument as an object or an ord
{arg: 'arg1', type: 'number', required: true}, {arg: 'arg1', type: 'number', required: true},
{arg: 'arg2', type: 'array'} {arg: 'arg2', type: 'array'}
] ]
```
**Types** **Types**
@ -467,6 +540,7 @@ Each argument may define any of the [loopback types](#loopback-types).
Run a function before or after a remote method is called by a client. Run a function before or after a remote method is called by a client.
```js
// *.save === prototype.save // *.save === prototype.save
User.beforeRemote('*.save', function(ctx, user, next) { User.beforeRemote('*.save', function(ctx, user, next) {
if(ctx.user) { if(ctx.user) {
@ -480,17 +554,21 @@ Run a function before or after a remote method is called by a client.
console.log('user has been saved', user); console.log('user has been saved', user);
next(); next();
}); });
```
Remote hooks also support wildcards. Run a function before any remote method is called. Remote hooks also support wildcards. Run a function before any remote method is called.
```js
// ** will match both prototype.* and *.* // ** will match both prototype.* and *.*
User.beforeRemote('**', function(ctx, user, next) { User.beforeRemote('**', function(ctx, user, next) {
console.log(ctx.methodString, 'was invoked remotely'); // users.prototype.save was invoked remotely console.log(ctx.methodString, 'was invoked remotely'); // users.prototype.save was invoked remotely
next(); next();
}); });
```
Other wildcard examples Other wildcard examples
```js
// run before any static method eg. User.find // run before any static method eg. User.find
User.beforeRemote('*', ...); User.beforeRemote('*', ...);
@ -511,6 +589,7 @@ Other wildcard examples
next(); next();
}); });
```
#### Context #### Context
@ -536,21 +615,22 @@ The express ServerRequest object. [See full documentation](http://expressjs.com/
The express ServerResponse object. [See full documentation](http://expressjs.com/api.html#res). The express ServerResponse object. [See full documentation](http://expressjs.com/api.html#res).
Access the raw `req` object for the remote method call.
#### Relationships #### Relationships
##### Model.hasMany(Model) ##### Model.hasMany(Model)
Define a "one to many" relationship. Define a "one to many" relationship.
```js
// by referencing model // by referencing model
Book.hasMany(Chapter); Book.hasMany(Chapter);
// specify the name // specify the name
Book.hasMany('chapters', {model: Chapter}); Book.hasMany('chapters', {model: Chapter});
```
Query and create the related models. Query and create the related models.
```js
Book.create(function(err, book) { Book.create(function(err, book) {
// create a chapter instance // create a chapter instance
// ready to be saved in the data source // ready to be saved in the data source
@ -577,6 +657,7 @@ Query and create the related models.
console.log(chapters); console.log(chapters);
}); });
}); });
```
#### Shared Methods #### Shared Methods
@ -588,6 +669,7 @@ A Loopback `DataSource` provides [Models](#model) with the ability to manipulate
Define a data source for persisting models. Define a data source for persisting models.
```js
var oracle = loopback.createDataSource({ var oracle = loopback.createDataSource({
connector: 'oracle', connector: 'oracle',
host: '111.22.333.44', host: '111.22.333.44',
@ -595,17 +677,21 @@ Define a data source for persisting models.
username: 'username', username: 'username',
password: 'password' password: 'password'
}); });
```
#### dataSource.createModel(name, properties, options) #### dataSource.createModel(name, properties, options)
Define a model and attach it to a `DataSource`. Define a model and attach it to a `DataSource`.
```js
var Color = oracle.createModel('color', {name: String}); var Color = oracle.createModel('color', {name: String});
```
#### dataSource.discoverModelDefinitions([username], fn) #### dataSource.discoverModelDefinitions([username], fn)
Discover a set of model definitions (table or collection names) based on tables or collections in a data source. Discover a set of model definitions (table or collection names) based on tables or collections in a data source.
```js
oracle.discoverModelDefinitions(function (err, models) { oracle.discoverModelDefinitions(function (err, models) {
models.forEach(function (def) { models.forEach(function (def) {
// def.name ~ the model name // def.name ~ the model name
@ -614,6 +700,7 @@ Discover a set of model definitions (table or collection names) based on tables
}); });
}); });
}); });
```
#### dataSource.discoverSchema([owner], name, fn) #### dataSource.discoverSchema([owner], name, fn)
@ -621,6 +708,7 @@ Discover the schema of a specific table or collection.
**Example schema from oracle connector:** **Example schema from oracle connector:**
```js
{ {
"name": "Product", "name": "Product",
"options": { "options": {
@ -711,6 +799,7 @@ Discover the schema of a specific table or collection.
} }
} }
} }
```
#### dataSource.enableRemote(operation) #### dataSource.enableRemote(operation)
@ -721,6 +810,7 @@ Enable remote access to a data source operation. Each [connector](#connector) ha
Disable remote access to a data source operation. Each [connector](#connector) has its own set of set enabled and disabled operations. You can always list these by calling `dataSource.operations()`. Disable remote access to a data source operation. Each [connector](#connector) has its own set of set enabled and disabled operations. You can always list these by calling `dataSource.operations()`.
```js
// all rest data source operations are // all rest data source operations are
// disabled by default // disabled by default
var oracle = loopback.createDataSource({ var oracle = loopback.createDataSource({
@ -731,6 +821,7 @@ Disable remote access to a data source operation. Each [connector](#connector) h
// or only disable it as a remote method // or only disable it as a remote method
oracle.disableRemote('destroyAll'); oracle.disableRemote('destroyAll');
```
**Notes:** **Notes:**
@ -746,6 +837,7 @@ List the enabled and disabled operations.
Output: Output:
```js
{ {
find: { find: {
remoteEnabled: true, remoteEnabled: true,
@ -762,14 +854,17 @@ Output:
}, },
... ...
} }
```
#### Connectors #### Connectors
Create a data source with a specific connector. See **available connectors** for specific connector documentation. Create a data source with a specific connector. See **available connectors** for specific connector documentation.
```js
var memory = loopback.createDataSource({ var memory = loopback.createDataSource({
connector: loopback.Memory connector: loopback.Memory
}); });
```
**Available Connectors** **Available Connectors**
@ -788,16 +883,19 @@ Create a data source with a specific connector. See **available connectors** for
Include the connector in your package.json dependencies and run `npm install`. Include the connector in your package.json dependencies and run `npm install`.
```js
{ {
"dependencies": { "dependencies": {
"loopback-connector-oracle": "latest" "loopback-connector-oracle": "latest"
} }
} }
```
##### Memory Connector ##### Memory Connector
The built-in memory connector allows you to test your application without connecting to an actual persistent data source, such as a database. Although the memory connector is very well tested it is not recommended to be used in production. Creating a data source using the memory connector is very simple. The built-in memory connector allows you to test your application without connecting to an actual persistent data source, such as a database. Although the memory connector is very well tested it is not recommended to be used in production. Creating a data source using the memory connector is very simple.
```js
// use the built in memory function // use the built in memory function
// to create a memory data source // to create a memory data source
var memory = loopback.memory(); var memory = loopback.memory();
@ -826,6 +924,7 @@ The built-in memory connector allows you to test your application without connec
function count() { function count() {
Product.count(console.log); // 3 Product.count(console.log); // 3
} }
```
###### Operations ###### Operations
@ -841,37 +940,47 @@ The memory connector also supports geo-filtering when using the `find()` operati
Use the `GeoPoint` class. Use the `GeoPoint` class.
```js
var GeoPoint = require('loopback').GeoPoint; var GeoPoint = require('loopback').GeoPoint;
```
Embed a latitude / longitude point in a [Model](#model). Embed a latitude / longitude point in a [Model](#model).
```js
var CoffeeShop = loopback.createModel('coffee-shop', { var CoffeeShop = loopback.createModel('coffee-shop', {
location: 'GeoPoint' location: 'GeoPoint'
}); });
```
Loopback Model's with a GeoPoint property and an attached DataSource may be queried using geo spatial filters and sorting. Loopback Model's with a GeoPoint property and an attached DataSource may be queried using geo spatial filters and sorting.
Find the 3 nearest coffee shops. Find the 3 nearest coffee shops.
```js
CoffeeShop.attachTo(oracle); CoffeeShop.attachTo(oracle);
var here = new GeoPoint({lat: 10.32424, lng: 5.84978}); var here = new GeoPoint({lat: 10.32424, lng: 5.84978});
CoffeeShop.find({where: {location: {near: here}}, limit:3}, function(err, nearbyShops) { CoffeeShop.find({where: {location: {near: here}}, limit:3}, function(err, nearbyShops) {
console.info(nearbyShops); // [CoffeeShop, ...] console.info(nearbyShops); // [CoffeeShop, ...]
}); });
```
#### geoPoint.distanceTo(geoPoint, options) #### geoPoint.distanceTo(geoPoint, options)
Get the distance to another `GeoPoint`. Get the distance to another `GeoPoint`.
```js
var here = new GeoPoint({lat: 10, lng: 10}); var here = new GeoPoint({lat: 10, lng: 10});
var there = new GeoPoint({lat: 5, lng: 5}); var there = new GeoPoint({lat: 5, lng: 5});
console.log(here.distanceTo(there, {type: 'miles'})); // 438 console.log(here.distanceTo(there, {type: 'miles'})); // 438
```
#### GeoPoint.distanceBetween(a, b, options) #### GeoPoint.distanceBetween(a, b, options)
Get the distance between two points. Get the distance between two points.
```js
GeoPoint.distanceBetween(here, there, {type: 'miles'}) // 438 GeoPoint.distanceBetween(here, there, {type: 'miles'}) // 438
```
#### Distance Types #### Distance Types
@ -924,6 +1033,7 @@ Register and authenticate users of your app locally or against 3rd party service
Extend a vanilla Loopback model using the built in User model. Extend a vanilla Loopback model using the built in User model.
```js
// create a data source // create a data source
var memory = loopback.memory(); var memory = loopback.memory();
@ -938,6 +1048,7 @@ Extend a vanilla Loopback model using the built in User model.
// expose over the app's api // expose over the app's api
app.model(User); app.model(User);
```
**Note:** By default the `loopback.User` model uses the `loopback.Session` model to persist sessions. You can change this by setting the `session` property. **Note:** By default the `loopback.User` model uses the `loopback.Session` model to persist sessions. You can change this by setting the `session` property.
@ -947,10 +1058,12 @@ Extend a vanilla Loopback model using the built in User model.
Create a user like any other model. Create a user like any other model.
```js
// username and password are not required // username and password are not required
User.create({email: 'foo@bar.com', password: 'bar'}, function(err, user) { User.create({email: 'foo@bar.com', password: 'bar'}, function(err, user) {
console.log(user); console.log(user);
}); });
```
##### Login a User ##### Login a User
@ -959,14 +1072,17 @@ Create a session for a user using the local auth strategy.
**Node.js** **Node.js**
```js
User.login({username: 'foo', password: 'bar'}, function(err, session) { User.login({username: 'foo', password: 'bar'}, function(err, session) {
console.log(session); console.log(session);
}); });
```
**REST** **REST**
You must provide a username and password over rest. To ensure these values are encrypted, include these as part of the body and make sure you are serving your app over https (through a proxy or using the https node server). You must provide a username and password over rest. To ensure these values are encrypted, include these as part of the body and make sure you are serving your app over https (through a proxy or using the https node server).
```
POST POST
/users/login /users/login
@ -983,11 +1099,13 @@ You must provide a username and password over rest. To ensure these values are e
"sid": "1234abcdefg", "sid": "1234abcdefg",
"uid": "123" "uid": "123"
} }
```
##### Logout a User ##### Logout a User
**Node.js** **Node.js**
```js
// login a user and logout // login a user and logout
User.login({"email": "foo@bar.com", "password": "bar"}, function(err, session) { User.login({"email": "foo@bar.com", "password": "bar"}, function(err, session) {
User.logout(session.id, function(err) { User.logout(session.id, function(err) {
@ -999,19 +1117,23 @@ You must provide a username and password over rest. To ensure these values are e
User.findOne({email: 'foo@bar.com'}, function(err, user) { User.findOne({email: 'foo@bar.com'}, function(err, user) {
user.logout(); user.logout();
}); });
```
**REST** **REST**
```
POST /users/logout POST /users/logout
... ...
{ {
"sid": "<session id from user login>" "sid": "<session id from user login>"
} }
```
##### Verify Email Addresses ##### Verify Email Addresses
Require a user to verify their email address before being able to login. This will send an email to the user containing a link to verify their address. Once the user follows the link they will be redirected to `/` and be able to login normally. Require a user to verify their email address before being able to login. This will send an email to the user containing a link to verify their address. Once the user follows the link they will be redirected to `/` and be able to login normally.
```js
User.requireEmailVerfication = true; User.requireEmailVerfication = true;
User.afterRemote('create', function(ctx, user, next) { User.afterRemote('create', function(ctx, user, next) {
var options = { var options = {
@ -1026,35 +1148,41 @@ Require a user to verify their email address before being able to login. This wi
user.verify(options, next); user.verify(options, next);
}); });
```
##### Send Reset Password Email ##### Send Reset Password Email
Send an email to the user's supplied email address containing a link to reset their password. Send an email to the user's supplied email address containing a link to reset their password.
```js
User.reset(email, function(err) { User.reset(email, function(err) {
console.log('email sent'); console.log('email sent');
}); });
```
##### Remote Password Reset ##### Remote Password Reset
The password reset email will send users to a page rendered by loopback with fields required to reset the user's password. You may customize this template by defining a `resetTemplate` setting. The password reset email will send users to a page rendered by loopback with fields required to reset the user's password. You may customize this template by defining a `resetTemplate` setting.
```js
User.settings.resetTemplate = 'reset.ejs'; User.settings.resetTemplate = 'reset.ejs';
```
##### Remote Password Reset Confirmation ##### Remote Password Reset Confirmation
Confirm the password reset. Confirm the password reset.
```js
User.confirmReset(token, function(err) { User.confirmReset(token, function(err) {
console.log(err || 'your password was reset'); console.log(err || 'your password was reset');
}); });
```
#### Session Model #### Session Model
Identify users by creating sessions when they connect to your loopback app. By default the `loopback.User` model uses the `loopback.Session` model to persist sessions. You can change this by setting the `session` property. Identify users by creating sessions when they connect to your loopback app. By default the `loopback.User` model uses the `loopback.Session` model to persist sessions. You can change this by setting the `session` property.
```js
// define a custom session model // define a custom session model
var MySession = loopback.Session.extend('my-session'); var MySession = loopback.Session.extend('my-session');
@ -1067,6 +1195,7 @@ Identify users by creating sessions when they connect to your loopback app. By d
// attach both Session and User to a data source // attach both Session and User to a data source
User.attachTo(loopback.memory()); User.attachTo(loopback.memory());
MySession.attachTo(loopback.memory()); MySession.attachTo(loopback.memory());
```
#### Email Model #### Email Model
@ -1076,7 +1205,9 @@ Send emails from your loopback app.
Expose models over rest using the `loopback.rest` router. Expose models over rest using the `loopback.rest` router.
```js
app.use(loopback.rest()); app.use(loopback.rest());
```
**REST Documentation** **REST Documentation**
@ -1086,5 +1217,6 @@ View generated REST documentation by visiting: [http://localhost:3000/_docs](htt
**Coming Soon** - Expose models over socket.io using the `loopback.sio()` middleware. **Coming Soon** - Expose models over socket.io using the `loopback.sio()` middleware.
```js
app.use(loopback.sio); app.use(loopback.sio);
```

View File

@ -1,5 +1,9 @@
##Concepts ##Concepts
###SDKs
**PLACEHOLDER FOR SDK INTRO**
###Model ###Model
LoopBack is centered around models. A model is an object that encapsulates data. A model is usually named after its real life counterpart. Like its real life counterpart a model has properties or attributes. LoopBack is centered around models. A model is an object that encapsulates data. A model is usually named after its real life counterpart. Like its real life counterpart a model has properties or attributes.

View File

@ -1,13 +1,13 @@
##LoopBack ##LoopBack
v1.0.0 **v1.0.0**
###Introduction > **Introduction**
>
LoopBack is a mobile backend framework that puts you in control. As a mobile developer you decide where to run your mobile backend - in the cloud or on permise. > LoopBack is a mobile backend framework that puts you in control. As a mobile developer you decide where to run your mobile backend - in the cloud or on permise.
LoopBack is built on open source Node.js and leverages the power of Node and the community that stands behind Node. > LoopBack is built on open source Node.js and leverages the power of Node and the community that stands behind Node.
>
LoopBack is here to help you develop mobile applications with rich functionality and data that is in your datacenter and the cloud. > LoopBack is here to help you develop mobile applications with rich functionality and data that is in your datacenter and the cloud.
Since LoopBack is built on open source, it is highly extensible and familiar with developers already using Node. > Since LoopBack is built on open source, it is highly extensible and familiar with developers already using Node.
Node.js leverages Javascript. The ubiquituous language of the web that most developers have already had familiarity with it's ease of use. > Node.js leverages Javascript. The ubiquituous language of the web that most developers have already had familiarity with it's ease of use.
--- ---

View File

@ -21,3 +21,5 @@ $ slc run app
**Step 5** Try out the various REST apis by clicking the button below. **Step 5** Try out the various REST apis by clicking the button below.
<a href="http://localhost:3000/explorer" class="status btn btn-primary">Explore the REST APIs</a> <a href="http://localhost:3000/explorer" class="status btn btn-primary">Explore the REST APIs</a>
---

View File

@ -1,9 +1,9 @@
#Model REST API ## REST API
LoopBack automatically binds a model to a list of HTTP endpoints that provide REST APIs for CRUD and other remote LoopBack automatically binds a model to a list of HTTP endpoints that provide REST APIs for CRUD and other remote
operations. operations.
##Sample Model ### Sample Model
We use the following `Location` model as an example to illustrate generated REST APIs. We use the following `Location` model as an example to illustrate generated REST APIs.
@ -83,7 +83,7 @@ The remoting is defined using the following properties:
- returns: Description of the return value - returns: Description of the return value
- http: Binding to the HTTP endpoint - http: Binding to the HTTP endpoint
##Generated APIs ###Generated APIs
###create ###create