Nic Jansma | nicj.net | @NicJ
npm install -g sails
sails new [project path]
cd [project path]
sails lift
info: Starting app...
info:
info:
info: Sails <|
info: v0.10.2 |\
info: /|.\
info: / || \
info: ,' |' \
info: .-'.-==|/_--'
info: `--'-------'
info: __---___--___---___--___---___--___
info: ____---___--___---___--___---___--___-__
info:
info: Server lifted in `example1`
info: To see your app, visit http://localhost:1337
info: To shut down Sails, press <CTRL> + C at any time.
debug: --------------------------------------------------------
debug: :: Thu Aug 07 2014 06:43:55 GMT-0400 (Eastern Daylight Time)
debug: Environment : development
debug: Port : 1337
debug: --------------------------------------------------------
Let's create a new beer model and REST API
sails generate api beer
This creates skeleton files: api\controllers\BeerController.js and
api\model\Beer.js
[]
http://localhost:1337/beer/create?name=Centennial IPA&brewery=Founders&have=10
{
"name": "All Day IPA",
"brewery": "Founders",
"createdAt": "2014-08-07T13:11:10.536Z",
"updatedAt": "2014-08-07T13:38:21.517Z",
"id": 1,
"have": 10
},
[
{
"name": "All Day IPA",
"brewery": "Founders",
"createdAt": "2014-08-07T13:11:10.536Z",
"updatedAt": "2014-08-07T13:38:21.517Z",
"id": 1,
"have": 10
}
]
Beer.js) and Controller (BeerController.js)POST /beer and /beer/create).api/controller/ - controllersapi/models/ - modelsapi/policies/ - authentication / authorizationapi/responses/ - res.xyz() handlersapi/services/ - servicesassets/ - static assetsconfig/ - app configtasks/ - grunt / cli tasksviews/ - viewsapi/models/*
module.exports = {
attributes: {
name: {
type: 'string',
required: true
},
brewery: {
type: 'string',
required: true
},
have: {
type: 'integer',
defaultTo: 1
}
}
};
api/controllers/*config/blueprints.js), you automatically get CRUD REST and "shortcut" routesBy default, Sails creates three types of blueprint routes:
/:model (HTTP GET, DELETE, etc)GET requests,
such as /:model/delete/:id (should be turned off in production)Authentication and access control are handled via policies
| REST | Shortcut | |
|---|---|---|
| Query | GET /api/:model | |
| Fetch | GET /api/:model/:id | |
| Create | POST /api/:model | GET /api/:model/create |
| Update | PUT /api/:model/:id | GET /api/:model/update/:id |
| Delete | DELETE /api/:model/:id | GET /api/:model/destroy/:id |
By default, Sails creates actions on your controllers for ORM functionality:
// config/routes.js
module.exports.routes = {
'/': {
view: 'homepage'
},
'post /beer/:id/drink': 'BeerController.drink'
}
// BeerController.js
module.exports = {
drink: function (req, res) {
if (!req.params.id) { return res.badRequest('ID not supplied'); }
Beer.findOne({ id: req.params.id }, function(err, model) {
if (err || !model) {
return res.badRequest('Beer not found');
}
model.have--;
model.save(function(err) {
return res.ok(model);
});
});
}
};
api/views/*
// BeerController.js
module.exports = {
show: function(req, res) {
Beer.find({}, function (err, beers) {
res.view('show-beers', { title: 'Beers', beers: beers });
});
}
};
// show-beers.ejs
<ul>
<% for(var i=0; i<beers.length; i++) {%>
<li><%= beers[i].name %></li>
<% } %>
</ul>
Sails automatically translates incoming socket.io messages into Express requests
Also gives you Pub/Sub via res.broadcast() and req.join()
var socket = io.connect('http://localhost:1337');
socket.request('/beer', {}, function(beers) { console.log(neers); });