# Learn Carthage

Carthage follows MVC patterns you're probably familiar with from the simplicity
of Django and Rails. If you need more in-depth help,
[full API documentation is available here](http://www.carthagejs.com/static/docs/index.html). Otherwise,
let's get started!

# Starting Your Project

To begin your project, first install the latest version of Node (4.x) from
[nodejs.org](http://nodejs.org). Once you've completed that, open your
tercarthagel and run:

```
npm install carthage -g
```
(If you get an error, run `sudo npm install carthage -g` or fix permissions permanently by [following these directions](https://docs.npmjs.com/getting-started/fixing-npm-permissions).
It will take a few seconds to finish. At this point, you have the Carthage
command line tools available and you can really get started!

Next, run:

```
carthage new
```

A few prompts will walk you through the project creation process. Once you're
done, visit your new project folder.

# Starting Your Server

Begin your Carthage server with:

```
carthage s
```

And voila! You'll notice the port that it's running on is `3000`. If you want to
change that, go to `config/secrets.json`:

```json
{

  "development": {
    "port": 3000,
  },

  "production": {
    "port": "{{= env.PORT }}",
  }

}
```

And modify the `"port": 3000,` line to whatever you'd like. Wait - is this magic?
Not really. **Every file in ./config/ will get loaded into a special Config object**.
Namely, into `Carthage.my.Config.{filename}` assuming `const Carthage = require('carthage')`.

Remember this! This is very important for setting environment variables. The
values that are loaded are based on your environment, set by your `NODE_ENV` environment
variable (defaults to development).

Let's see why the server is running on port 3000 by looking in `./cluster.js`...

```javascript
module.exports = (() => {

  'use strict';

  const Carthage = require('carthage');
  const cluster = require('cluster');

  if (cluster.isMaster) {

    const daemon = Carthage.require('app/daemon.js');
    daemon.start(Carthage.my.Config.secrets.PORT);

  } else {

    const app = new Carthage.Application();
    app.listen(Carthage.my.Config.secrets.PORT);


  }

})();
```

Not so magic after all. We're telling the server daemon to start, and once it's running,
to telling any application processes that spawn to listen on the provided port.

# Routing

Your server has started, but how do HTTP requests know where to go? Easy,
let's look in `./app/router.js`.

```javascript
module.exports = (function() {

  'use strict';

  const Carthage = require('carthage');
  const router = new Carthage.Router();

  /* Middleware */
  /* executed *before* Controller-specific middleware */

  const CORSMiddleware = Carthage.require('middleware/cors_middleware.js');
  // const ForceWWWMiddleware = Carthage.require('middleware/force_www_middleware.js');
  // const ForceHTTPSMiddleware = Carthage.require('middleware/force_https_middleware.js');

  router.middleware.use(CORSMiddleware);
  // router.middleware.use(ForceWWWMiddleware);
  // router.middleware.use(ForceHTTPSMiddleware);

  /* Renderware */
  /* executed *after* Controller-specific renderware */

  const GzipRenderware = Carthage.require('renderware/gzip_renderware.js')

  router.renderware.use(GzipRenderware);

  /* Routes */

  const IndexController = Carthage.require('app/controllers/index_controller.js');
  const StaticController = Carthage.require('app/controllers/static_controller.js');
  const Error404Controller = Carthage.require('app/controllers/error/404_controller.js');

  /* generator: begin imports */


  /* generator: end imports */

  router.route('/').use(IndexController);
  router.route('/static/*').use(StaticController);

  /* generator: begin routes */


  /* generator: end routes */

  router.route('/*').use(Error404Controller);

  return router;

})();
```

Things to make note of here: The design pattern for `module.exports = (function() { /*...*/ })()`
where you export an IIFE is the standard in Carthage. The reason we do this is to encourage
consistency in understanding what's getting exported. A developer looking to quickly debug
can jump to the bottom of a file and look for the return statement to see what was
actually exported.

First we see Middleware and Renderware being added to the Controller. Middleware
set on the router is executed *for every endpoint*, and happens *before*
Controller-specific middleware. Renderware is similarly executed on every
endpoint, but happens *after* Controller-specific renderware. The execution
flow looks like this...

```
Client Request ->
Controller#before ->
Router Middleware ->
Controller Middleware ->
Controller#get, put, post, del ->
Controller Renderware ->
Router Renderware ->
Controller#after ->
Server Response
```

Next, **Controllers are all loaded very explicitly**. This follows Django's routing
style. The router itself takes regex and will compare an incoming request to its
pattern in the order that they're added.

Also make note of the `/* generator: ... */` lines. These are used as boilerplate
for automatic controller importing / route addition from the command line file generators.
You should avoid removing these lines.

We see in the basic routing structure that we check to hit the index and the static
folder before going through generated routes (special cases) and finally fall
back to a 404 if nothing is hit.

# Controllers

So what exactly happens when you hit the index route? Exploring `./app/controllers/index_controller.js`
gives us the answer.

```javascript
module.exports = (function() {

  'use strict';

  const Carthage = require('carthage');

  class IndexController extends Carthage.Controller {

    get() {

      this.render(
        Carthage.Template.generate('index.html').render(
          this.params,
          {
            name: 'My Carthage Application'
          }
        )
      );

    }

  }

  return IndexController;

})();
```

When the index route is hit, a new *instance* of `IndexController` is created.
This is given some special properties accessible from referring to the instance.
Within a method, `this.params` contains client request parameters (`this.params.query`,
  `this.params.id`, `this.params.body`, `this.params.ip_address`, etc.) and
  `this.app` refers to your main `Application` instance, incase you need
  to access any "global" properties from it.

We can see here a `get()` method, which is called when an HTTP `GET` request
comes to the controller. Anything not specified will fall back to a
`501 - Not Implemented` response. Available methods that can be triggered from
a route are:

```javascript
get()
post()
put()
del()
options()
```

Or, some CRUD-like equivalents:
```javascript
index() // GET with no this.params.id
show() // GET with a this.params.id
create() // POST
update() // PUT
destroy() // DELETE
```

To render a string from within a controller, use `this.render()`. It can also
render JSON automatically if you provide a serializable object. **For API-formatted
responses use:** `this.respond()`. Other ways to respond to requests are
available [in the API documentation](http://www.carthagejs.com/static/docs/index.html).

## Using 'this' in Controllers

Please keep in mind that ES6 arrow functions (`fnAdd = (a, b) => a + b;`)
*do not create a new context for* `this`. If you have nested callbacks
in a Controller (quite common), it is a best practice to keep using anonymous
arrow functions to preserve your reference to the controller instance so responses
are easy to send out. (No `self = this;` anti-patterns.)

## Creating Controllers with the CLI

Create a new controller with the CLI using

```
carthage g:controller ControllerName
```

It will then create `controller_name_controller.js` in the base `./controllers/` directory.

If you'd like to put it in another directory, use:

```
carthage g:controller path/to/ControllerName
```

**Generating controllers this way will also automatically create best-guess routes
in router.js.**

You can create a controller for a specific model (auto include CRUD features) with:

```
carthage g:controller --for ModelName
```

# Models

Creating models is easy. Your project won't start out with any (they're not
necessary for all server types), but you can generate them with:

```
carthage g:model ModelName
```

This will create both a *Model* and a *Migration*. The Model will look like;

```javascript
module.exports = (function() {

  'use strict';

  const Carthage = require('carthage');

  class ModelName extends Carthage.Model {}

  ModelName.setDatabase(Carthage.require('db/main.js'));
  ModelName.setSchema(Carthage.my.Schema.models.ModelName);

  return ModelName;

})();
```

Our database is set from `./db/main.js` which grabs connection data from
`./config/db.json`. (Explore both files to see what's happening. Same as
`./config/secrets.json` above.) Note that Carthage currently only supports PostgreSQL.

Our schema is set from `Carthage.my.Schema` which automatically loaded `./db/schema.json`
upon starting the server. (**For this reason, Schema changes require app shutdowns and reloads.**)

## Special Models

Carthage comes with two "special", pre-built models. `User` and `AccessToken`.
Create these with:

```
carthage g:model --user
carthage g:model --access_token
```

These models just have some additional libraries / functionality included that
make things like passwords and OAuth a little bit easier. [Part 2 of the Introduction
screencast](https://www.youtube.com/watch?v=cQW4tgQsV_I) begins to cover this.

## Migrating Your Model

With your Model, a Migration was created in `./db/migrations`. In order to load
your Model data into a schema and create the necessary database connections,
make sure PostgreSQL is running and make sure your database is created:

```
carthage db:create
```

Once your database is created, prepare it for migrations (drops schema, clears table)

```
carthage db:prepare
```

And finally, run all pending migrations with:

```
carthage db:migrate
```

If you need to undo a migration simply run (one migration at a time):

```
carthage db:rollback
```

If you'd like to do a stepwise migrations or rollbacks, use the flag:

```
carthage db:migrate --step:1
```

## Using Your Model

To use your Model in a controller, import it with:

```
const Model = Carthage.require('app/models/my_model.js');
```

`Carthage.require` is just `require` pointing to your main app directory.

You can do fun things with your Model like;

```javascript
let myModel = new MyModel({field1: 'a', field2: 'b'}); // create a Model, not in db
myModel.save(err, callback); // Save model instance to db
myModel.destroy(err, callback); // Remove model instance from db
Model.create(params, callback); // creates and saves your model to db right away
Model.find(id, callback); // find a Model with a specified id
Model.update(id, params, callback); // update a Model with a specified id
Model.destroy(id, callback); // ... etc.

/* And queries! */
let query = Model.query(); // Instantiate Composer (ORM instance)


// method chaining :)
query
  .where({id__gt: 7})
  .orderBy('id', 'DESC')
  .limit(5)
  .where({field1__like: 'lol'})
  .end((err, myModels) => {

    // do something with my models

  });
```

## Postgres JSONB Column Type support

Carthage has basic support for the Postgres [JSONB data type](http://www.postgresql.org/docs/9.4/static/datatype-json.html). Any model that has a json column that contains a valid JSON object will have the object automatically marshalled in and out of the database. Let's walk through how to setup and use a model with a json column.

First, lets generate a new model

```carthage g:model Recipe name:string, flags:json```

Open the migration that was generated and you will see the following in the `up()` method.

```javascript
this.createTable("recipes", [{"name":"name","type":"string,"},{"name":"flags","type":"json"}])
```
Let's modify the up command to add an index on the json column. Your `up()` method should look something like this

```javascript    
up() {

  return [
    this.createTable("recipes", [{"name":"name","type":"string,"},{"name":"flags","type":"json"}])
    this.createIndex("recipes", "flags", "gin")
  ];

}
```

Carthage provides two comparator's for querying the json data for matches or existence. Lets assume our Recipe table contains a collection of recipes, and the flags json column contains flags related to dietary restrictions like vegetarian, vegan or paleo. Lets query for recipes that are Paleo only

```javascript
Recipe.query()
      .where({flags__json:{ paleo: true }})
      .end( (err,recipes) => {
        ......
      });
```

The `__json` comparator also allows for multi key queries:

```javascript
Recipe.query()
      .where({flags__json:{ vegan: true, paleo: true }})
      .end( (err,recipes) => {
        ......
      });
```




What if you want to query for all recipes that contain a certain key.

```javascript
Recipe.query()
      .where({flags__jsoncontains: 'paleo'})
      .end( (err,recipes) => {
        ......
      });
```


## What Now?

There's still a bunch more to cover! Information on in-depth Migrations,
Middleware, Schedulers, Tasks and Workers is coming soon.

Please [watch the repository, keithwhor/carthage](http://github.com/keithwhor/carthage)
for updates.

Keep up with screencasts and more details on [carthagejs.com](http://carthagejs.com).

Follow me on Twitter, [@keithwhor](http://twitter.com/keithwhor)
