Model documentation
This commit is contained in:
parent
a9f27183fa
commit
1db52a60d6
44
README.md
44
README.md
|
@ -4,6 +4,50 @@ v0.0.1
|
|||
## Install
|
||||
|
||||
slnode install asteroid -g
|
||||
|
||||
## API
|
||||
|
||||
### app
|
||||
|
||||
Create an asteroid app.
|
||||
|
||||
var asteroid = require('asteroid')
|
||||
, app = asteroid();
|
||||
|
||||
### app.dataSource()
|
||||
|
||||
Attach a remote data source to your app.
|
||||
|
||||
app.dataSource('color-db', {
|
||||
adapter: 'oracle',
|
||||
host: 'localhost',
|
||||
port: 2345,
|
||||
user: 'test',
|
||||
password: 'test'
|
||||
});
|
||||
|
||||
### app.define(name)
|
||||
|
||||
Define a [Model](node_modules/model).
|
||||
|
||||
var Color = app.define('color');
|
||||
|
||||
### app.use(asteroid.rest);
|
||||
|
||||
Expose your models over a REST api.
|
||||
|
||||
// node
|
||||
app.use(asteroid.rest);
|
||||
|
||||
// http
|
||||
GET /colors
|
||||
|
||||
200 OK
|
||||
[
|
||||
{name: 'red'},
|
||||
{name: 'blue'},
|
||||
{name: 'green'}
|
||||
]
|
||||
|
||||
## Asteroid Modules
|
||||
|
||||
|
|
|
@ -5,6 +5,18 @@ v0.0.1
|
|||
|
||||
Asteroid applications are a combination of regular Node.js modules and Asteroid modules. Asteroid modules may be initialized using JavaScript or by writing config files.
|
||||
|
||||
## Using Asteroid Modules
|
||||
|
||||
There are two distinct ways to use an Asteroid Module in your application.
|
||||
|
||||
### App API
|
||||
|
||||
The `app` API allows you to define [data sources](../data-source) and [models](../model) in regular Node JavaScript. [See the docs for more info](../../readme.md#API).
|
||||
|
||||
### Config Files
|
||||
|
||||
You may also define [data sources](../data-source), [models](../model) and other asteroid modules by writing `config.json` files. See the documentation for a given module to see what config data it requires.
|
||||
|
||||
## Extending Asteroid
|
||||
|
||||
The core of asteroid is very lightweight and unopionated. All features are added on as `AsteroidModule`s. This means you can add your own functionality, modify existing functionality, or extend existing functionality by creating your own `AsteroidModule` class.
|
||||
|
|
|
@ -4,6 +4,224 @@
|
|||
|
||||
A `Model` represents the data of your application. Asteroid `Model`s are mostly used for validating interactions with a [DataSource](../data-source). Usually your models will correspond to a namespace in your data source (database table, http url, etc). The bulk of your application's business logic will be in your `Model` or Node.js scripts that require your model.
|
||||
|
||||
## Data Definition Language
|
||||
|
||||
TODO ~ document
|
||||
|
||||
## API
|
||||
|
||||
### Defining Models
|
||||
|
||||
The following assumes your have reference to a class that inherits from `Model`. The simplest way to get this is by using the [app API](../../readme.md#API).
|
||||
|
||||
// define a model class using the app api
|
||||
var Color = app.define('color');
|
||||
|
||||
// provide an exact plural name
|
||||
var Color = app.define('color', {plural: 'colors'});
|
||||
|
||||
**Note:** If a plural name is not defined, the model will try to pluralize the singular form.
|
||||
|
||||
#### MyModel.defineSchema(schema)
|
||||
|
||||
Define the data the model represents using the data definition language.
|
||||
|
||||
// define the color model
|
||||
var Color = app.define('color');
|
||||
|
||||
// define the schema for the Color model
|
||||
Color.defineSchema({
|
||||
name: 'string',
|
||||
id: 'uid',
|
||||
tweets: 'array'
|
||||
});
|
||||
|
||||
##### MyModel.dataSource(name, namespace)
|
||||
|
||||
Set the data source for the model. Must provide a name of an existing data source. If the `namespace` is not provided the plural model name (eg. `colors`) will be used.
|
||||
|
||||
// set the data source
|
||||
Color.dataSource('color-db', 'COLOR_NAMES');
|
||||
|
||||
**Note:** If you do not set a data source or a map (or both) the default data source will be used (an in memory database).
|
||||
|
||||
#### MyModel.defineMap(map)
|
||||
|
||||
Define a mapping between the data source representation of your data and your app's representation.
|
||||
|
||||
// manually map Color to existing table columns
|
||||
Color.defineMap({
|
||||
dataSource: 'color-db', // optional, will use model's data source
|
||||
table: 'COLOR_NAMES', // required
|
||||
map: { // optional if schema defined
|
||||
id: 'COLOR_ID',
|
||||
name: 'COLOR_NAME'
|
||||
}
|
||||
});
|
||||
|
||||
// mix in a mapping from another data source
|
||||
Color.defineMap({
|
||||
dataSource: 'twitter',
|
||||
url: function(color) {
|
||||
return '/search?limit=5&q=' + color.name;
|
||||
},
|
||||
map: {
|
||||
// provides the color.tweets property
|
||||
tweets: function(tweets) {
|
||||
return tweets;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
**Note:** You may define multiple maps for a single model. The model will combine the data for you.
|
||||
|
||||
#### MyModel.discoverSchema(fn)
|
||||
|
||||
Using the mapped data source, try to discover the schema of a table or other namespace (url, collection, etc).
|
||||
|
||||
// use existing schema to map to desired properties
|
||||
Color.dataSource('color-db', 'COLOR_NAMES');
|
||||
Color.discoverSchema(function (err, oracleSchema) {
|
||||
var schema = {tweets: 'array'};
|
||||
var map = {dataSource: 'color-db', table: 'COLOR_NAMES'};
|
||||
|
||||
// inspect the existing table schema to create a mapping
|
||||
Object
|
||||
.keys(oracleSchema)
|
||||
.forEach(function (oracleProperty) {
|
||||
// remove prefix
|
||||
var property = oracleProperty.toLowerCase().split('_')[0];
|
||||
|
||||
// build new schema
|
||||
schema[property] = oracleProperty[oracleProperty];
|
||||
// create mapping to existing schema
|
||||
map[property] = oracleProperty;
|
||||
});
|
||||
|
||||
Color.defineSchema(schema);
|
||||
Color.defineMap(map);
|
||||
});
|
||||
|
||||
### Custom Methods
|
||||
|
||||
There are two types of custom methods. Static and instance.
|
||||
|
||||
**Static**
|
||||
|
||||
Static methods are available on the Model class itself and are used to operate on many models at the same time.
|
||||
|
||||
**Instance**
|
||||
|
||||
Instance methods are available on an instance of a Model and usually act on a single model at a time.
|
||||
|
||||
#### Defining a Static Method
|
||||
|
||||
The following example shows how to define a simple static method.
|
||||
|
||||
Color.myStaticMethod = function() {
|
||||
// only has access to other static methods
|
||||
this.find(function(err, colors) {
|
||||
console.log(colors); // [...]
|
||||
});
|
||||
}
|
||||
|
||||
#### Defining an Instance Method
|
||||
|
||||
The following is an example of a simple instance method.
|
||||
|
||||
Color.prototype.myInstanceMethod = function() {
|
||||
console.log(this.name); // red
|
||||
}
|
||||
|
||||
#### Remotable Methods
|
||||
|
||||
Both types of methods may be set as `remotable` as long as they conform to the remotable requirements. Asteroid will expose these methods over the network for you.
|
||||
|
||||
##### Remotable Requirements
|
||||
|
||||
Static and instance methods must accept a callback as the last argument. This callback must be called with an error as the first argument and the results as arguments afterward.
|
||||
|
||||
You must also define the input and output of your remoteable method. Describe the input or arguments of the function by providing an `accepts` array and describe the output by defining a `returns` array.
|
||||
|
||||
// this method meets the remotable requirements
|
||||
Color.getByName = function (name, callback) {
|
||||
Color.find({where: {name: name}}, function (err, colors) {
|
||||
// if an error occurs callback with the error
|
||||
if(err) {
|
||||
callback(err);
|
||||
} else {
|
||||
callback(null, colors);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// accepts a name of type string
|
||||
Color.getByName.accepts = [
|
||||
{arg: 'name', type: 'String'} // data definition language
|
||||
];
|
||||
|
||||
// returns an array of type Color
|
||||
Color.getByName.returns = [
|
||||
{arg: 'colors', type: ['Color']} // data definition language
|
||||
];
|
||||
|
||||
**Note:** any types included in `accepts`/`returns` must be native JavaScript types or Model classes.
|
||||
|
||||
### Working with Models
|
||||
|
||||
The following assumes you have access to an instance of a `Model` class.
|
||||
|
||||
// define a model
|
||||
var Color = app.define('color');
|
||||
|
||||
// create an instance
|
||||
var color = new Color({name: red});
|
||||
|
||||
#### myModel.save([options], [callback])
|
||||
|
||||
**Remoteable**
|
||||
|
||||
Save the model using its configured data source.
|
||||
|
||||
var color = new Color();
|
||||
color.name = 'green';
|
||||
|
||||
// fire and forget
|
||||
color.save();
|
||||
|
||||
// callback
|
||||
color.save(function(err, color) {
|
||||
if(err) {
|
||||
console.log(err); // validation or other error
|
||||
} else {
|
||||
console.log(color); // updated with id
|
||||
}
|
||||
});
|
||||
|
||||
#### myModel.destroy([callback])
|
||||
|
||||
**Remoteable**
|
||||
|
||||
Delete the instance using attached data source. Invoke callback when ready.
|
||||
|
||||
var color = Color.create({id: 10});
|
||||
|
||||
color.destroy(function(err) {
|
||||
if(err) {
|
||||
console.log(err); // could not destroy
|
||||
} else {
|
||||
console.log('model has been destroyed!');
|
||||
}
|
||||
});
|
||||
|
||||
#### MyModel.all()
|
||||
#### MyModel.find()
|
||||
#### MyModel.count()
|
||||
|
||||
### Model Relationships
|
||||
|
||||
## Config
|
||||
|
||||
### Options
|
||||
|
||||
#### namespace
|
||||
|
@ -34,4 +252,4 @@ An array of properties describing the model's schema.
|
|||
|
||||
#### data source
|
||||
|
||||
A [data-source](../data-source) for persisting data.
|
||||
The name of a data source [data-source](../data-source) for persisting data.
|
Loading…
Reference in New Issue