Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/t4t5/november-cli
❄️ Generate a Node.js API for your Ember.js app
https://github.com/t4t5/november-cli
database ember ember-data nodejs sequelize
Last synced: 20 days ago
JSON representation
❄️ Generate a Node.js API for your Ember.js app
- Host: GitHub
- URL: https://github.com/t4t5/november-cli
- Owner: t4t5
- License: mit
- Created: 2015-05-20T19:56:33.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2017-01-14T10:31:49.000Z (almost 8 years ago)
- Last Synced: 2024-12-01T22:40:47.588Z (23 days ago)
- Topics: database, ember, ember-data, nodejs, sequelize
- Language: JavaScript
- Homepage:
- Size: 1.08 MB
- Stars: 51
- Watchers: 9
- Forks: 10
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
![November logo](https://raw.githubusercontent.com/t4t5/november-cli/master/november-logo.png)
November helps you generate a simple Node.js API tailored for [Ember.js](http://emberjs.com) apps, with the help of [Express](http://expressjs.com) and [Sequelize](http://docs.sequelizejs.com/en/latest).
Installation
------------
```bash
$ npm install -g november-cli
```Get started
-----------
```bash
$ november new my-app
```
This will create a new project with the following structure:
```
├── app
│ ├── actions
│ ├── controllers
│ ├── middleware
│ ├── models
│ ├── router.js
│
├── config
│ ├── config.json
│
├── lib
├── migrations
├── node_modules
├── public
├── server.js
├── test
```By default, MySQL is used as a database, but you can use any relational database [supported by Sequelize](http://docs.sequelizejs.com/en/latest) by changing the values in `config/config.json`.
To run the app, run `npm start` (or just `nodemon` if you have it installed) in your app’s directory and visit `localhost:9000`.
In your Ember.js app
--------------------Make sure you change the host in your Ember.js adapter file so that it can communicate with November:
```bash
# In your ember project folder
$ ember generate adapter
```
```javascript
// app/adapters/application.js
import DS from "ember-data";export default DS.RESTAdapter.reopen({
host: 'http://localhost:9000'
});
```Models
------
```bash
$ november generate model user
```This generates:
- A **model file** (`app/models/user.js`) for the user, which will determine the structure of the database table
- **Routes** in `app/router.js` for creating, reading, updating and deleting users (based on the conventions of Ember Data). Feel free to remove the actions you don't need.
- **Controller files**, which hook up the routes to database actions:
- `app/controllers/user/add.js`
- `app/controllers/user/list.js`
- `app/controllers/user/load.js`
- `app/controllers/user/update.js`
- `app/controllers/user/remove.js`With the app and your local database running in the background, visit `localhost:9000/users`, and you should see:
```json
{
"users": []
}
```
The table `users` has automatically been created in your database.Actions
-------
Actions are for API endpoints which are not specifically tied to any model.
```bash
$ november generate action login
```This generates:
- An **action file** (`app/actions/login.js`)
- A **route** in `app/router.js` (`POST` by default)Render()
-------
The `render()`-method in your controllers is used for rendering both your *models* and your *error messages*. It takes a single argument.Rendering models
-------------
If you pass a valid sequelize model to `render()`, it will generate that model according to the [JSON API](http://jsonapi.org) conventions used by Ember Data.The most basic usage:
```
render();
```
...which can also be typed like this:
```
render({
model:
});
```
returns:
```javascript
{
"user": {
<...>
}
}
```If your sequelize model includes [associated models](http://docs.sequelizejs.com/en/latest/api/associations), they are sideloaded by default:
```javascript
{
"user": {
<...>
"tweets": [1, 5]
},
"tweets": [
<...>
]
}
```However, you can also specify if you want some (or all) associations to be embedded instead.
Here we specify that we want the tweets-association to be embedded. If we wanted *all* associations to be embedded, we would set `embedded: true`
```javascript
render({
model: ,
embedded: ['tweets']
});
```
... which returns:
```javascript
{
"user": {
<...>
"tweets": [
{
id: 1,
<...>
},
{
id: 5,
<...>
}
]
}
}
```Rendering errors
---------------Controllers generated by November rely heavily on promises. If they catch an error, they call `render(error)`.
Let's say we accidentally search for a field (`name`) which doesn't exist in our database table:
```javascript
// app/controllers/user/list.js
req.models.user
.findAll({
where: {
name: "Bob"
}
})
.then(function(users) {
// Not gonna happen
})
.catch(function(err) {
render(err);
});
```An error will be catched and `render(err)` will return this JSON to the client:
```json
{
"error": {
"code": 500,
"message": "Could not load users"
}
}
```
... while still showing a more descriptive error to the developer in the console so that you can locate the problem:![A console error](http://tristanedwards.me/u/november/console-error.png)
You can also render your own exceptions to the user, by throwing a **string** with the error message or an **array** where the first element is the error code and the second is the error message:
```javascript
// app/controllers/user/update.js
req.models.user.find({
where: {
username: req.params.username
}
})
.then(function(user) {
if (user.id !== req.user) {
throw [403, "You are not allowed to edit this user!"]
}
return user.save();
})
.then(function(user) {
// Not gonna happen
})
.catch(function(err) {
render(err);
});
```...what the client will see:
```json
{
"error": {
"code": 403,
"message": "You are not allowed to edit this user!"
}
}
```Todos
-----
TDD is not really my thing, but it would be nice to get some automatic Mocha tests when you generate new models. :)Contact
-------If you have any questions, feel free to [ping me on Twitter](https://twitter.com/t4t5) or just open an issue!