strongloop/loopback — pull request #57 by ritch (2013-10-29 22:34:17+00:00)
Title: Add support for "booting" an application from a set of Model / DataSource / app meta-data.

/to @raymondfeng
/cc @bajtos @piscisaureus @sam-github @themitchy

## Background

[Here is a detailed example application](https://github.com/ritch/loopback-project-example/pull/1) using the new `app.boot()` api. The sample app shows how using `app.boot()` can simplify our project structure.

## Current Project Structure

Currently `slc lb` generates a set of modules and an entry file (`app.js`). `app.js` is a module loader that is baked in as part of the generated code. It `require()`s each module in the modules directory and starts the app. Each module is made up of generated code (`index.js`) a module description (`module.json`) that defines meta-data about the module and one or more config files (`config.json`, `properties.json`).

## Issues with the Current Structure

> "There are too many files named `index.js`"

> "data sources, apps, models, are all top-level structures without explicit type in the folder hierarchy"

Since each "module" contains an `index.js` file, working on a loopback project usually means having several `index.js` files open. The example project linked above has clearly named files and directories (eg. `models.json`, `./models`).

> "A bare scaffolded model consists of 3 files and many lines, none of which I know what they are for."

The proposed structure wouldn't include any extra generated files. Instead `slc lb` would just update the `models.json` file when scaffolding a model or `datasources.json` when defining a datasource.

## Propsoed Project Structure

The structure proposed in the example linked above is a bit simpler. There are three config files:

- app.json
- models.json
- datasources.json

Plus a single entry file:

- app.js

`app.js` is the only file with generated code. It includes the following:

```js
var loopback = require('loopback');
var app = module.exports = loopback();

// express compatible middleware
app.use(loopback.favicon());
app.use(loopback.logger('dev'));
app.use(loopback.bodyParser());
app.use(loopback.methodOverride());
app.use(app.router);
app.use(loopback.static(path.join(__dirname, 'public')));

// configure the app
// read more:
app.boot();

// development only
if ('development' == app.get('env')) {
app.use(loopback.errorHandler());
}

// only start the server if this module
// is the main module...
if(require.main === module) {
app.listen();
}
```

When `app.boot()` is called without any arguments, the following is kicked off:

1. **DataSources** are created from `datasources.json` in the current directory
2. **Models** are created from `models.json` in the current directory
3. Any JavaScript files in the `./models` dir are required.

## New Simpler APIs

This PR also introduces a simpler way of defining and interacting with models:

First you define the data sources your app requires using `app.boot()`.

```js
app.boot({
dataSources: {
mongo: {connector: "mongodb", url: "mongodb://localhost:27015/my-db"}
}
});
```

Then you can define a model in a single line:

```js
var Product = app.model('product', {dataSource: 'mongo'});
```

Furthermore, your models are available from your `app`.

```js
Product = require('../app').models.Product;
```

**Read the updated documentation for more info.**