Model documentation

This commit is contained in:
Ritchie Martori 2013-04-26 11:44:19 -07:00
parent a9f27183fa
commit 1db52a60d6
3 changed files with 275 additions and 1 deletions

View File

@ -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

View File

@ -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.

220
node_modules/model/README.md generated vendored
View File

@ -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.