From e6cdeb5cd4a1b8d57c007da6b3107d1ba572677e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Mon, 13 Jan 2014 17:02:32 +0100 Subject: [PATCH 1/3] Improve jsdox documentation of app object Remove docs/api-app.md and docs/api.md, as they are no longer referenced from docs.json. Add few missing bits from docs/api-app.md to lib/application.js comments. --- docs/api-app.md | 255 --------------------------------------------- docs/api.md | 8 -- lib/application.js | 88 ++++++++++++++-- 3 files changed, 80 insertions(+), 271 deletions(-) delete mode 100644 docs/api-app.md delete mode 100644 docs/api.md diff --git a/docs/api-app.md b/docs/api-app.md deleted file mode 100644 index 28dbf87b..00000000 --- a/docs/api-app.md +++ /dev/null @@ -1,255 +0,0 @@ -## App object - -The App object represents a Loopback application. - -The App object extends [Express](http://expressjs.com/api.html#express) and supports [Express / Connect middleware](http://expressjs.com/api.html#middleware). See [Express documentation](http://expressjs.com/api.html) for details. - -```js -var loopback = require('loopback'); -var app = loopback(); - -app.get('/', function(req, res){ - res.send('hello world'); -}); - -app.listen(3000); -``` - -## Properties - -### models - -The `app.models` object has properties for all defined models. In the following example the `Product` and `CustomerReceipt` models are accessed using the `models` object. - -**NOTE:** you must call `app.boot()` to create the `app.models` object. - -```js -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; -``` - -## Methods - -### app.boot([options]) - -Initialize an application from an options object or a set of JSON and JavaScript files. - -**What happens during an app _boot_?** - -1. **DataSources** are created from an `options.dataSources` object or `datasources.json` in the current directory -2. **Models** are created from an `options.models` object or `models.json` in the current directory -3. Any JavaScript files in the `./models` directory are loaded with `require()`. -4. Any JavaScript files in the `./boot` directory are loaded with `require()`. - -**Options** - - - `cwd` - _optional_ - the directory to use when loading JSON and JavaScript files - - `models` - _optional_ - an object containing `Model` definitions - - `dataSources` - _optional_ - an object containing `DataSource` definitions - -> **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. - - -**Model Definitions** - -The following is an example of an object containing two `Model` definitions: "location" and "inventory". - -```js -{ - "dealership": { - // a reference, by name, to a dataSource definition - "dataSource": "my-db", - // the options passed to Model.extend(name, properties, options) - "options": { - "relationships": { - "cars": { - "type": "hasMany", - "model": "Car", - "foreignKey": "dealerId" - } - }, - "remoteMethods": { - "nearby": { - "description": "Find nearby locations around the geo point", - "accepts": [ - {"arg": "here", "type": "GeoPoint", "required": true, "description": "geo location (lat & lng)"} - ], - "returns": {"arg": "locations", "root": true} - } - } - }, - // 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 - } - } - } -} -``` - -**Model definition properties** - - - `dataSource` - **required** - a string containing the name of the data source definition to attach the `Model` to - - `options` - _optional_ - an object containing `Model` options - - `properties` _optional_ - an object defining the `Model` properties in [LoopBack Definition Language](http://docs.strongloop.com/loopback-datasource-juggler/#loopback-definition-language) - -**DataSource definition properties** - - - `connector` - **required** - the name of the [connector](#working-with-data-sources-and-connectors) - -### model(name, definition) - -Define a `Model` and export it for use by remote clients. - -**definition** - -- `public` - **default: true** attach the `Model` to the app and export its methods to clients -- `dataSource` - **required** the name of the `DataSource` to attach the `Model` to - -Example: - -```js -// declare a DataSource -app.boot({ - dataSources: { - db: { - connector: 'mongodb', - url: 'mongodb://localhost:27015/my-database-name' - } - } -}); - -// describe a model -var modelDefinition = {dataSource: 'db'}; - -// create the model -var Product = app.model('product', modelDefinition); - -// use the model api -Product.create({name: 'pencil', price: 0.99}, console.log); -``` - -**Note** - This will expose all [shared methods](#shared-methods) on the model. - -You may also export an existing `Model` by calling `app.model(Model)` like the example below. - -### models() - -Get the app's exported models. Only models defined using `app.model()` will show up in this list. - -```js -var models = app.models(); - -models.forEach(function (Model) { - console.log(Model.modelName); // color -}); -``` - -### docs(options) - -Enable swagger REST API documentation. - -**Options** - - - `basePath` The basepath for your API - eg. 'http://localhost:3000'. - -**Example** - -```js -// enable docs -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. - -### app.use( router ) - -Expose models over specified router. -For example, to expose models over REST using the `loopback.rest` router: - -```js -app.use(loopback.rest()); -``` - -View generated REST documentation at [http://localhost:3000/_docs](http://localhost:3000/_docs). - -### Middleware - -LoopBack includes middleware similar to [Express / Connect middleware](http://expressjs.com/api.html#middleware). - -#### loopback.token(options) - -**Options** - - - `cookies` - An `Array` of cookie names - - `headers` - An `Array` of header names - - `params` - An `Array` of param names - -Each 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`. - -```js -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. - -```js - params.push('access_token'); - headers.push('X-Access-Token'); - headers.push('authorization'); - cookies.push('access_token'); - cookies.push('authorization'); -``` - -> **NOTE:** The `loopback.token()` middleware will only check for [signed cookies](http://expressjs.com/api.html#req.signedCookies). diff --git a/docs/api.md b/docs/api.md deleted file mode 100644 index ae4021e5..00000000 --- a/docs/api.md +++ /dev/null @@ -1,8 +0,0 @@ -## Node.js API - - * [App](#app-object) - * [DataSource](#data-source-object) - * [GeoPoint](#geopoint-object) - * [Model](#model-object) - * [Remote methods and hooks](#remote-methods-and-hooks) - * [REST API](#rest-api) diff --git a/lib/application.js b/lib/application.js index 6497441f..746a5e4f 100644 --- a/lib/application.js +++ b/lib/application.js @@ -31,10 +31,10 @@ var DataSource = require('loopback-datasource-juggler').DataSource * ``` * * @class LoopBackApplication - * @header app = loopback() + * @header var app = loopback() */ function App() { - // no op + // this is a dummy placeholder for jsdox } /*! @@ -122,9 +122,55 @@ app.model = function (Model, config) { } /** - * Get all exposed models. + * Get the models exported by the app. Only models defined using `app.model()` + * will show up in this list. + * + * There are two ways how to access models. + * + * **1. A list of all models** + * + * Call `app.models()` to get a list of all models. + * + * ```js + * var models = app.models(); + * + * models.forEach(function (Model) { + * console.log(Model.modelName); // color + * }); + * ``` + * + * **2. By model name** + * + * `app.model` has properties for all defined models. + * + * In the following example the `Product` and `CustomerReceipt` models are + * accessed using the `models` object. + * + * ```js + * 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; + * ``` * - * @header app.models() or app.models.ModelName * @returns {Array} a list of model classes */ @@ -172,8 +218,28 @@ app.remotes = function () { return this._remotes || (this._remotes = RemoteObjects.create()); } -/*! - * Enable documentation +/** + * Enable swagger REST API documentation. + * + * > Note: This method is deprecated, use the extension + * [loopback-explorer](http://npmjs.org/package/loopback-explorer) instead. + * + * **Options** + * + * - `basePath` The basepath for your API - eg. 'http://localhost:3000'. + * + * **Example** + * + * ```js + * // enable docs + * 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. + * + * @deprecated */ app.docs = function (options) { @@ -254,7 +320,13 @@ app.enableAuth = function() { * - `cwd` - _optional_ - the directory to use when loading JSON and JavaScript files * - `models` - _optional_ - an object containing `Model` definitions * - `dataSources` - _optional_ - an object containing `DataSource` definitions - * + * + * > **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. + * * * **Model Definitions** * @@ -314,7 +386,7 @@ app.enableAuth = function() { * * - `connector` - **required** - the name of the [connector](#working-with-data-sources-and-connectors) * - * + * @header app.boot([options]) * @throws {Error} If config is not valid * @throws {Error} If boot fails */ From 8be4d095e299565386a16a4d53ae3760e8dfe552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Mon, 13 Jan 2014 19:47:27 +0100 Subject: [PATCH 2/3] Remove docs/rest.md The documentation of the REST interface is maintained on docs.strongloop.com --- docs.json | 3 +- docs/rest.md | 495 --------------------------------------------------- 2 files changed, 1 insertion(+), 497 deletions(-) delete mode 100644 docs/rest.md diff --git a/docs.json b/docs.json index eb68a22b..348ba7f7 100644 --- a/docs.json +++ b/docs.json @@ -15,8 +15,7 @@ "docs/api-datasource.md", "docs/api-geopoint.md", "docs/api-model.md", - "docs/api-model-remote.md", - "docs/rest.md" + "docs/api-model-remote.md" ], "assets": "/docs/assets" } diff --git a/docs/rest.md b/docs/rest.md deleted file mode 100644 index 66c4dc0e..00000000 --- a/docs/rest.md +++ /dev/null @@ -1,495 +0,0 @@ -##create - -Create a new instance of the model and persist it into the data source - -**Definition** - - POST /locations - -**Arguments** - -* **data** The model instance data - - -**Example** - -Request: - - curl -X POST -H "Content-Type:application/json" \ - -d '{"name": "L1", "street": "107 S B St", "city": "San Mateo", "zipcode": "94401"}' \ - http://localhost:3000/locations - -Response: - - { - "id": "96", - "street": "107 S B St", - "city": "San Mateo", - "zipcode": 94401, - "name": "L1", - "geo": { - "lat": 37.5670042, - "lng": -122.3240212 - } - } - -**Errors** - -None - -##upsert - -Update an existing model instance or insert a new one into the data source - -**Definition** - - PUT /locations - -**Arguments** - -* **data** The model instance data - -**Examples** - -Request - insert: - - curl -X PUT -H "Content-Type:application/json" \ - -d '{"name": "L1", "street": "107 S B St", "city": "San Mateo", "zipcode": "94401"}' \ - http://localhost:3000/locations - -Response: - - { - "id": "98", - "street": "107 S B St", - "city": "San Mateo", - "zipcode": 94401, - "name": "L1", - "geo": { - "lat": 37.5670042, - "lng": -122.3240212 - } - } - -Request - update: - - curl -X PUT -H "Content-Type:applicatin/json" \ - -d '{"id": "98", "name": "L4", "street": "107 S B St", "city": "San Mateo", \ - "zipcode": "94401"}' http://localhost:3000/locations - -Response: - - { - "id": "98", - "street": "107 S B St", - "city": "San Mateo", - "zipcode": 94401, - "name": "L4" - } - - -**Errors** - -None - -##exists - -Check whether a model instance exists by ID in the data source. - -**Definition** - - GET /locations/exists - -**Arguments** - -* **id** The model id - -**Example** - -Request: - - curl http://localhost:3000/locations/88/exists - -Response: - - { - "exists": true - } - -**Errors** - -None - -##findById - -Find a model instance by ID from the data source. - -**Definition** - - GET /locations/{id} - -**Arguments** - -* **id** The model id - -**Example** - -Request: - - curl http://localhost:3000/locations/88 - -Response: - - { - "id": "88", - "street": "390 Lang Road", - "city": "Burlingame", - "zipcode": 94010, - "name": "Bay Area Firearms", - "geo": { - "lat": 37.5874391, - "lng": -122.3381437 - } - } - -**Errors** - -None - -##find - -Find all instances of the model matched by filter from the data source. - -**Definition** - - GET /locations - -**Arguments** - -Pass the arguments as the value of the `find` HTTP query parameter, as follows - - /modelName?filter=[filterType1]=&filter[filterType2]=... - -where *filterType1*, *filterType2*, and so on, are the filter types, and *val1*, *val2* are the corresponding -values, as described in the following table. - -| Filter type | Type | Description | -| ------------- | ------------- | ---------------| -| where | Object | Search criteria. Format: `{key: val}` or `{key: {op: val}}` For list of valid operations, see Operations, below. | -| include | String, Object, or Array | Allows you to load relations of several objects and optimize numbers of requests. For format, see Include format, below. | -| order | String | Sort order. Format: 'key1 ASC, key2 DESC', where ASC specifies ascending and DESC specifies descending order. | -|limit| Number | Maximum number of instances to return. | -|skip (offset) | Number | Skip the specified number of instances. Use offset as alternative. | -|fields| Object, Array, or String | The included/excluded fields. For foramt, see fields below. - -**Operations available in where filter**: - - * gt: > - * gte: >= - * lt: < - * lte: <= - * between - * inq: IN - * nin: NOT IN - * neq: != - * like: LIKE - * nlike: NOT LIKE - -**Include format**: - - * 'posts': Load posts - * ['posts', 'passports']: Load posts and passports - * {'owner': 'posts'}: Load owner and owner's posts - * {'owner': ['posts', 'passports']}: Load owner, owner's posts, and owner's passports - * {'owner': [{posts: 'images'}, 'passports']}: Load owner, owner's posts, owner's posts' images, and owner's passports - -**Fields format**: - - - `['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 bat - -For example, - - - '/weapons': Weapons - - '/weapons?filter[limit]=2&filter[offset]=5': Paginated Weapons - - '/weapons?filter[where][name]=M1911': Weapons with name M1911 - - '/weapons?filter[where][audibleRange][lt]=10': Weapons with audioRange < 10 - - '/weapons?filter[fields][name]=1&filter[fields][effectiveRange]=1': Only name and effective ranges - - '/weapons?filter[where][effectiveRange][gt]=900&filter[limit]=3': The top 3 weapons with a range over 900 meters - - '/weapons?filter[order]=audibleRange%20DESC&filter[limit]=3': The loudest 3 weapons - - - '/locations': Locations - - '/locations?filter[where][geo][near]=153.536,-28.1&filter[limit]=3': The 3 closest locations to a given geo point - - -**Example** - -Request: - -Find without filter: - - curl http://localhost:3000/locations - -Find with a filter: - - curl http://localhost:3000/locations?filter%5Blimit%5D=2 - -**Note**: For curl, `[` needs to be encoded as `%5B`, and `]` as `%5D`. - -Response: - - [ - { - "id": "87", - "street": "7153 East Thomas Road", - "city": "Scottsdale", - "zipcode": 85251, - "name": "Phoenix Equipment Rentals", - "geo": { - "lat": 33.48034450000001, - "lng": -111.9271738 - } - }, - { - "id": "88", - "street": "390 Lang Road", - "city": "Burlingame", - "zipcode": 94010, - "name": "Bay Area Firearms", - "geo": { - "lat": 37.5874391, - "lng": -122.3381437 - } - } - ] - -**Errors** - -None - -##findOne - -Find first instance of the model matched by filter from the data source. - -**Definition** - - GET /locations/findOne - -**Arguments** - -* **filter** The filter that defines where, order, fields, skip, and limit. It's -same as find's filter argument. Please see [find](#find) for more details. - -**Example** - -Request: - - curl http://localhost:3000/locations/findOne?filter%5Bwhere%5D%5Bcity%5D=Scottsdale - -Response: - - { - "id": "87", - "street": "7153 East Thomas Road", - "city": "Scottsdale", - "zipcode": 85251, - "name": "Phoenix Equipment Rentals", - "geo": { - "lat": 33.48034450000001, - "lng": -111.9271738 - } - } - -**Errors** - -None - -##deleteById - -Delete a model instance by id from the data source - -**Definition** - - DELETE /locations/{id} - -**Arguments** - -* **id** The model id - -**Example** - -Request: - - curl -X DELETE http://localhost:3000/locations/88 - -Response: - -Example TBD. - -**Errors** - -None - -##count - -Count instances of the model matched by where from the data source - -**Definition** - - GET /locations/count - -**Arguments** - -* **where** The criteria to match model instances - -**Example** - -Request - count without "where" filter - - curl http://localhost:3000/locations/count - -Request - count with a "where" filter - - curl http://localhost:3000/locations/count?where%5bcity%5d=Burlingame - -Response: - - { - count: 6 - } - -**Errors** - -None - -##nearby - -Find nearby locations around the geo point. - -**Definition** - - GET /locations/nearby - -**Arguments** - -* **here** geo location object with `lat` and `lng` properties -* **page** number of pages (page size=10) -* **max** max distance in miles - -**Example** - -Request: - - curl http://localhost:3000/locations/nearby?here%5Blat%5D=37.587409&here%5Blng%5D=-122.338225 - -Response: - - [ - { - "id": "88", - "street": "390 Lang Road", - "city": "Burlingame", - "zipcode": 94010, - "name": "Bay Area Firearms", - "geo": { - "lat": 37.5874391, - "lng": -122.3381437 - } - }, - { - "id": "89", - "street": "1850 El Camino Real", - "city": "Menlo Park", - "zipcode": 94027, - "name": "Military Weaponry", - "geo": { - "lat": 37.459525, - "lng": -122.194253 - } - } - ] - -**Errors** - -None - -##updateAttributes - -Update attributes for a model instance and persist it into the data source - -**Definition** - - PUT /locations/{id} - -**Arguments** - -* **data** An object containing property name/value pairs -* **id** The model id - -**Example** - -Request: - - curl -X PUT -H "Content-Type:application/json" -d '{"name": "L2"}' \ - http://localhost:3000/locations/88 - -Response: - - { - "id": "88", - "street": "390 Lang Road", - "city": "Burlingame", - "zipcode": 94010, - "name": "L2", - "geo": { - "lat": 37.5874391, - "lng": -122.3381437 - }, - "state": "CA" - } - -**Errors** - -* 404 No instance found for the given id - -##getAssociatedModel - -Follow the relations from one model (`location`) to another one (`inventory`) to -get instances of the associated model. - -**Definition** - - GET /locations/{id}/inventory - -**Arguments** - -* **id** The id for the location model - -**Example** - -Request: - - curl http://localhost:3000/locations/88/inventory - -Response: - - [ - { - "productId": "2", - "locationId": "88", - "available": 10, - "total": 10 - }, - { - "productId": "3", - "locationId": "88", - "available": 1, - "total": 1 - } - ] - -**Errors** - -None From eabe29bb7362558daad04762ab0982d1de12b666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Wed, 15 Jan 2014 08:50:54 +0100 Subject: [PATCH 3/3] Fix heading levels in docs/ markdown files. --- docs/api-datasource.md | 14 ++++----- docs/api-geopoint.md | 12 +++---- docs/api-model-remote.md | 10 +++--- docs/api-model.md | 68 ++++++++++++++++++++-------------------- 4 files changed, 53 insertions(+), 51 deletions(-) diff --git a/docs/api-datasource.md b/docs/api-datasource.md index b921e3b0..24f6f73f 100644 --- a/docs/api-datasource.md +++ b/docs/api-datasource.md @@ -14,9 +14,9 @@ var oracle = loopback.createDataSource({ }); ``` -## Methods +### Methods -### dataSource.createModel(name, properties, options) +#### dataSource.createModel(name, properties, options) Define a model and attach it to a `DataSource`. @@ -42,7 +42,7 @@ var Customer = ds.createModel('Customer', { }); ``` -### 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. @@ -57,7 +57,7 @@ oracle.discoverModelDefinitions(function (err, models) { }); ``` -### dataSource.discoverSchema([owner], name, fn) +#### dataSource.discoverSchema([owner], name, fn) Discover the schema of a specific table or collection. @@ -156,12 +156,12 @@ Discover the schema of a specific table or collection. } ``` -### dataSource.enableRemote(operation) +#### dataSource.enableRemote(operation) Enable remote access to a data source operation. Each [connector](#connector) has its own set of set remotely enabled and disabled operations. You can always list these by calling `dataSource.operations()`. -### dataSource.disableRemote(operation) +#### dataSource.disableRemote(operation) 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()`. @@ -184,7 +184,7 @@ oracle.disableRemote('destroyAll'); - disabling the remoting for a method only affects client access (it will still be available from server models) - data sources must enable / disable operations before attaching or creating models -### dataSource.operations() +#### dataSource.operations() List the enabled and disabled operations. diff --git a/docs/api-geopoint.md b/docs/api-geopoint.md index 91db42e8..73eca7b7 100644 --- a/docs/api-geopoint.md +++ b/docs/api-geopoint.md @@ -40,9 +40,9 @@ CoffeeShop.find({where: {location: {near: here}}, limit:3}, function(err, nearby - `feet` - `degrees` -## Methods +### Methods -### geoPoint.distanceTo(geoPoint, options) +#### geoPoint.distanceTo(geoPoint, options) Get the distance to another `GeoPoint`. @@ -52,7 +52,7 @@ var there = new GeoPoint({lat: 5, lng: 5}); console.log(here.distanceTo(there, {type: 'miles'})); // 438 ``` -### GeoPoint.distanceBetween(a, b, options) +#### GeoPoint.distanceBetween(a, b, options) Get the distance between two points. @@ -60,12 +60,12 @@ Get the distance between two points. GeoPoint.distanceBetween(here, there, {type: 'miles'}) // 438 ``` -## Properties +### Properties -### geoPoint.lat +#### geoPoint.lat The latitude point in degrees. Range: -90 to 90. -### geoPoint.lng +#### geoPoint.lng The longitude point in degrees. Range: -180 to 180. diff --git a/docs/api-model-remote.md b/docs/api-model-remote.md index 1c30bdab..9098f275 100644 --- a/docs/api-model-remote.md +++ b/docs/api-model-remote.md @@ -2,7 +2,9 @@ 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. -### loopback.remoteMethod(fn, [options]) +### Static Methods + +#### loopback.remoteMethod(fn, [options]) Expose a remote method. @@ -118,7 +120,7 @@ as follows (assuming `name` as the name of the input parameter to resolve): then the value of `args['name']` is used if it is defined. 2. Otherwise `req.param('name')` is returned. -## Remote hooks +### Remote hooks Run a function before or after a remote method is called by a client. @@ -185,9 +187,9 @@ A `Model` representing the user calling the method remotely. **Note:** this is u 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. -#### Rest +#### REST -When [loopback.rest](#loopbackrest) is used the following `ctx` properties are available. +When [loopback.rest](#loopbackrest) is used the following additional `ctx` properties are available. ##### ctx.req diff --git a/docs/api-model.md b/docs/api-model.md index a7128605..6a96e45a 100644 --- a/docs/api-model.md +++ b/docs/api-model.md @@ -31,9 +31,9 @@ var User = loopback.createModel('user', { }); ``` -## Methods +### Methods -### 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. @@ -51,9 +51,9 @@ User.attachTo(oracle); **Note:** until a model is attached to a data source it will **not** have any **attached methods**. -## Properties +### Properties -### Model.properties +#### Model.properties An object containing a normalized set of properties supplied to `loopback.createModel(name, properties)`. @@ -92,7 +92,7 @@ Outputs: } ``` -## CRUD and Query Mixins +### CRUD and Query Mixins Mixins are added by attaching a vanilla model to a [data source](#data-source) with a [connector](#connectors). Each [connector](#connectors) 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()`. @@ -146,11 +146,11 @@ Here is the definition of the `count()` operation. } ``` -## Static Methods +### Static Methods **Note:** These are the default mixin methods for a `Model` attached to a data source. See the specific connector for additional API documentation. -### Model.create(data, [callback]) +#### Model.create(data, [callback]) Create an instance of Model with given data and save to the attached data source. Callback is optional. @@ -162,7 +162,7 @@ User.create({first: 'Joe', last: 'Bob'}, function(err, user) { **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`. -### Model.count([query], callback) +#### Model.count([query], callback) Query count of Model instances in data source. Optional query param allows to count filtered set of Model instances. @@ -172,7 +172,7 @@ User.count({approved: true}, function(err, count) { }); ``` -### Model.find(filter, callback) +#### Model.find(filter, callback) Find all instances of Model, matched by query. Fields used for filter and sort should be declared with `{index: true}` in model definition. @@ -230,7 +230,7 @@ User.find({ **Note:** See the specific connector's [docs](#connectors) for more info. -### Model.destroyAll([where], callback) +#### Model.destroyAll([where], callback) Delete all Model instances from data source. **Note:** destroyAll method does not perform destroy hooks. @@ -242,7 +242,7 @@ Product.destroyAll({price: {gt: 99}}, function(err) { > **NOTE:* `where` is optional and a where object... do NOT pass a filter object -### Model.findById(id, callback) +#### Model.findById(id, callback) Find instance by id. @@ -252,7 +252,7 @@ User.findById(23, function(err, user) { }); ``` -### Model.findOne(where, callback) +#### Model.findOne(where, callback) Find a single instance that matches the given where expression. @@ -262,11 +262,11 @@ User.findOne({id: 23}, function(err, user) { }); ``` -### Model.upsert(data, callback) +#### Model.upsert(data, callback) Update when record with id=data.id found, insert otherwise. **Note:** no setters, validations or hooks applied when using upsert. -### Custom static methods +#### Custom static methods Define a static model method. @@ -307,11 +307,11 @@ loopback.remoteMethod( ); ``` -## Instance methods +### Instance methods **Note:** These are the default mixin methods for a `Model` attached to a data source. See the specific connector for additional API documentation. -### model.save([options], [callback]) +#### model.save([options], [callback]) Save an instance of a Model to the attached data source. @@ -326,7 +326,7 @@ joe.save(function(err, user) { }); ``` -### model.updateAttributes(data, [callback]) +#### model.updateAttributes(data, [callback]) Save specified attributes to the attached data source. @@ -337,7 +337,7 @@ user.updateAttributes({ }, fn); ``` -### model.destroy([callback]) +#### model.destroy([callback]) Remove a model from the attached data source. @@ -347,7 +347,7 @@ model.destroy(function(err) { }); ``` -### Custom instance methods +#### Custom instance methods Define an instance method. @@ -363,9 +363,9 @@ Define a remote model instance method. loopback.remoteMethod(User.prototype.logout) ``` -## Relationships +### Relationships -### Model.hasMany(Model, options) +#### Model.hasMany(Model, options) Define a "one to many" relationship. @@ -407,7 +407,7 @@ Book.create(function(err, book) { }); ``` -### Model.belongsTo(Model, options) +#### Model.belongsTo(Model, options) 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 @@ -428,7 +428,7 @@ in one of the following styles: post.author(user) // Set the author to be the given user ``` -### Model.hasAndBelongsToMany(Model, options) +#### Model.hasAndBelongsToMany(Model, options) A `hasAndBelongsToMany` relation creates a direct many-to-many connection with another model, with no intervening model. For example, if your application @@ -443,9 +443,9 @@ appearing in many groups, you could declare the models this way, user.groups.remove(group, callback); // remove the user from the group ``` -## Validations +### Validations -### Model.validatesFormatOf(property, options) +#### Model.validatesFormatOf(property, options) Require a model to include a property that matches the given format. @@ -453,7 +453,7 @@ Require a model to include a property that matches the given format. User.validatesFormat('name', {with: /\w+/}); ``` -### Model.validatesPresenceOf(properties...) +#### Model.validatesPresenceOf(properties...) Require a model to include a property to be considered valid. @@ -461,7 +461,7 @@ Require a model to include a property to be considered valid. User.validatesPresenceOf('first', 'last', 'age'); ``` -### Model.validatesLengthOf(property, options) +#### Model.validatesLengthOf(property, options) Require a property length to be within a specified range. @@ -469,7 +469,7 @@ Require a property length to be within a specified range. 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. @@ -477,7 +477,7 @@ Require a value for `property` to be in the specified array. 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. @@ -485,7 +485,7 @@ Require a value for `property` to not exist in the specified array. 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`. @@ -493,7 +493,7 @@ Require a value for `property` to be a specific type of `Number`. 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. @@ -509,7 +509,7 @@ Currently supported in these connectors: - [Oracle](http://github.com/strongloop/loopback-connector-oracle) - [MongoDB](http://github.com/strongloop/loopback-connector-mongodb) -### myModel.isValid() +#### myModel.isValid() Validate the model instance. @@ -526,7 +526,7 @@ user.isValid(function (valid) { }); ``` -### loopback.ValidationError +#### loopback.ValidationError `ValidationError` is raised when the application attempts to save an invalid model instance. @@ -582,6 +582,6 @@ MyModel.prototype.preflight = function(changes, callback) { } ``` -## Shared methods +### Shared methods Any static or instance method can be decorated as `shared`. These methods are exposed over the provided transport (eg. [loopback.rest](#rest)).