Sails 是一套我相當喜歡的 Node.js web framework,底層仍然是使用 Express.js,另外整合了很多常用的 web 套件:grunt, socket.io, RESTful API, ......等。
由於 sails 的架構與 codeigniter 相當類似,Controller 對應到 View,並且對應到 route,在 config 中有個 controller.js 還可以對所有的 controller 做設定,如自動產生 restful api 等,以及這次的重點「prefix」,prefix 設定後在 route 上就會自動改變如下
使用 prefix 前
http://localhost/CONTROLLER_NAME/ACTION_NAME
使用 prefix 後( prefix 設定為 '/api/')
http://localhost/api/CONTROLLER_NAME/ACTION_NAME
如果只是要做 api server 相信這會是個很棒的設計,還可以作為 api 的版本區分(例如「/api/v1/」),但要做「網站」在 view 與 api 之間就必須做些區分,以下的作法就是將 view 與 api 切開,view 統一由 ViewController 控制,其他的 api 交由一般的 controller 控制,從 route 看起來如下
// ViewController
// Get user or user's view
http://localhost/user
// UserController
// Get user '1' api
http://localhost/api/user/1
資料夾目錄如下
/api /adapters ... /controllers ViewController.js ... /models ... /services ... /assets /bower_components ... /images ... /scripts ... /styles ... /fonts ... favicon.ico robots.txt /config /locales ... 404.js 500.js adapters.js bootstrap.js controller.js cors.js csrf.js i18n.js local.js log.js policies.js routes.js session.js sockets.js views.js /node_modules ... /views /home index.ejs ... .bowerrc .gitignore app.js bower.json Gruntfile.js package.json README.md
接下來開始實作把 api 與 view 切開
首先是設定好 api 的 prefix,修改 「/config/controllers.js」
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
/** * Controllers * * By default, Sails controllers automatically bind routes for each of their functions. * Additionally, each controller will automatically bind routes for a CRUD API * controlling the model which matches its name, if one exists. * * NOTE: These settings are for the global configuration of controllers. * You may also override these settings on a per-controller basis * by modifying the 'blueprints' object in your controllers * * For more information on controller configuration and blueprints, check out: * http://sailsjs.org/#documentation */ module.exports.controllers = { blueprints: { // Optional mount path prefix for blueprints // (the automatically bound routes in your controllers) // e.g. '/api/v2' prefix: '/api', // Whether routes are automatically generated for every action in your controllers // (also maps `index` to /:controller) // '/:controller', '/:controller/index', and '/:controller/:action' actions: true, // ** NOTE ** // These CRUD shortcuts exist for your convenience during development, // but you'll want to disable them in production. // '/:controller/find/:id?' // '/:controller/create' // '/:controller/update/:id' // '/:controller/destroy/:id' shortcuts: true, // Automatic REST blueprints enabled? // e.g. // 'get /:controller/:id?' // 'post /:controller' // 'put /:controller/:id' // 'delete /:controller/:id' rest: true, // If a blueprint route catches a request, // only match :id param if it's an integer // // e.g. only trigger route handler if requests look like: // get /user/8 // instead of: // get /user/a8j4g9jsd9ga4ghjasdha expectIntegerId: false } };
再來是設定 route 把 view 改為 '/',修改「/config/routes.js」
routes.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
/** * Routes * * Sails uses a number of different strategies to route requests. * Here they are top-to-bottom, in order of precedence. * * For more information on routes, check out: * http://sailsjs.org/#documentation */ module.exports.routes = { '/': 'ViewController.index', '/:page': { controller: 'ViewController', action: 'page' } };
最後是產生 ViewController,在 terminal 輸入
sails generate controller view
並修改 「/api/controllers/ViewController.js」
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
/** * ViewController * * @module :: Controller * @description :: Contains logic for handling requests. */ module.exports = { index: function(req, res) { console.log('viewController index begin'); return res.view('home/index.ejs', { // layout default in the same folder // layout: 'layout', }); }, /** * redirect to right page * i.e http://localhost:3000/user * ^^^^^^ * page = user * controller will redirect to ViewController/user * * @param {String} page redirect to page */ page: function(req, res) { var page = req.param('page'); return sails.controllers.view[page](req, res); }, user: function(req, res) { return res.view('user/index.ejs'); } };
ps. 或許也可以直接做 single page design,但某些狀況下透過 controller 可以從 server side 將其他訊息一併回給前端
完整的 code 可至 Gist 查看
相關連結
Sails
Node.js
grunt
socket.io
Express.js
codeigniter
沒有留言:
張貼留言