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); });