摘要:原文鏈接為什么使用前言入手半年,從用開(kāi)發(fā)自己的博客到用開(kāi)發(fā)公司項(xiàng)目,深深被震撼了。我不知道官方是否解釋過(guò)為什么要用個(gè)單詞,但以我的理解,的是負(fù)責(zé)指揮每一條客戶(hù)端請(qǐng)求應(yīng)該分配到服務(wù)器端的哪個(gè)去,所以叫藍(lán)圖吧。
前言原文鏈接:BlueSun | 為什么使用Sails?
入手Node.js半年,從用Express開(kāi)發(fā)自己的博客到用Sails開(kāi)發(fā)公司項(xiàng)目,深深被Sails震撼了。Sails是Balderdash團(tuán)隊(duì)的產(chǎn)品,快速的項(xiàng)目構(gòu)建、優(yōu)秀的框架結(jié)構(gòu)還有眾多的擴(kuò)展,讓我有種相見(jiàn)恨晚的感覺(jué)。在Koa流行之前,個(gè)人認(rèn)為Sails的用戶(hù)量還是挺可觀的。今天,我想寫(xiě)一寫(xiě)Sails那些讓我感動(dòng)的地方,順便理順一下Sails的架構(gòu)。
目錄一步搭建項(xiàng)目一步搭建項(xiàng)目
項(xiàng)目架構(gòu)
ORM
MVC的實(shí)現(xiàn)
路由
安全
日志
單元測(cè)試
WebSocket
在安裝了Node.js 和 Sails的環(huán)境下,只需要一條命令,就能夠搭建一個(gè)擁有完整架構(gòu)的項(xiàng)目,盡管這很簡(jiǎn)單,我還是覺(jué)得有必要說(shuō)一下。
在已經(jīng)安裝了Node.js和npm的前提下,首先你需要全局下安裝Sails
$ sudo npm install sails -g
其次在一個(gè)空路徑下,新建一個(gè)項(xiàng)目
$ sails new newApp
最后,只需要前往項(xiàng)目路徑,把項(xiàng)目運(yùn)行起來(lái)
$ cd testProject
$ sails lift
訪(fǎng)問(wèn) http://localhost:1337就能看到一個(gè)新的項(xiàng)目
項(xiàng)目架構(gòu). ├── api │?? ├── controllers │?? ├── models │?? ├── policies │?? ├── responses │?? └── services ├── views ├── assets ├── config ├── tasks ├── node_modules ├── package.json ├── Gruntfile.js ├── README.md └── app.jsapi/
api 目錄下是你要構(gòu)建應(yīng)用的核心所在,常說(shuō)的MVC的設(shè)計(jì)結(jié)構(gòu)就體現(xiàn)在這里
api/controllers :控制層,該層是Http請(qǐng)求的入口。Sails官方建議該層只處理請(qǐng)求的轉(zhuǎn)發(fā)和頁(yè)面的渲染,具體的邏輯實(shí)現(xiàn)應(yīng)該交給Service層。
api/models:模型層,在Sails中,對(duì)于Model采用的是充血模型,除了可以在模型中定于屬性之外,還可以定義包含邏輯處理的函數(shù)。在Sails中,所有Model都可以全局性訪(fǎng)問(wèn)。
api/policies:過(guò)濾層,該層在Controller層之前對(duì)Http請(qǐng)求做處理,在這一層中,可以定于一些規(guī)則來(lái)過(guò)濾Http請(qǐng)求,比如身份認(rèn)證什么的。
api/responses:http響應(yīng)的方法都放這里,例如服務(wù)器錯(cuò)誤、請(qǐng)求錯(cuò)誤、404錯(cuò)誤等,定義在responses文件夾里面的方法,都會(huì)賦值到controller層的req對(duì)象中。
api/services:服務(wù)層,該層包含邏輯處理的方法,在Sails中,所有Service都可以全局性訪(fǎng)問(wèn)。
視圖層,存放視圖模版文件的地方,Sails默認(rèn)是提供ejs模版引擎的,如果你愿意,你可以換成jade、handlebars或者任何你喜歡的模版引擎。
assets/資源文件夾,在Sails啟動(dòng)的時(shí)候,會(huì)啟動(dòng)某一個(gè)Grunt任務(wù),把a(bǔ)ssets文件夾里的內(nèi)容或壓縮或編譯或復(fù)制到根目錄下的.tmp目錄,這是前端可以直接通過(guò)路由訪(fǎng)問(wèn)的資源,HTML、JS、CSS以及圖片等靜態(tài)資源都放在這里了。
config/配置文件夾,在Sails啟動(dòng)的時(shí)候,會(huì)加載該文件夾里的文件,并賦值在全局對(duì)象sails.config中,所以能夠在任何一個(gè)地方都能用到。在用Sails開(kāi)發(fā),會(huì)經(jīng)常跟這個(gè)文件夾里的文件打交道,從config的構(gòu)成很容易知道Sails都提供哪方面的功能。
tasks/Sails自帶的項(xiàng)目自動(dòng)化工具是Grunt,而Grunt的配置和任務(wù)注冊(cè)都放在這個(gè)文件夾里了。這里已經(jīng)提供了通常會(huì)用到的CSS編譯、JS壓縮、文件合并,更改檢測(cè)等等任務(wù),當(dāng)然如果沒(méi)有自己需要的,還能擴(kuò)展。
app.jsSails的啟動(dòng)文件,無(wú)論是$ sails lift命令或者$ npm start命令都會(huì)運(yùn)行該文件。
ORM開(kāi)發(fā)了Sails的團(tuán)隊(duì)Balderdash,還開(kāi)發(fā)了一套ORM框架:Waterline。
Waterline在Sails主要的舞臺(tái)是在/api/models目錄里,在這里定義的模型文件,在Sails啟動(dòng)的時(shí)候,都要經(jīng)由Waterline的洗禮。
Waterline 是通過(guò)Adapter關(guān)聯(lián)數(shù)據(jù)庫(kù)的,不同的Adapter關(guān)聯(lián)不同的數(shù)據(jù)庫(kù)。
Waterline 能適配絕對(duì)部分?jǐn)?shù)據(jù)庫(kù),大致分類(lèi)兩類(lèi),一類(lèi)是官方團(tuán)隊(duì)開(kāi)發(fā)的 Adapter適配的,一類(lèi)是民間開(kāi)發(fā)者開(kāi)發(fā)的Adapter適配的:
官方支持的:
PostgreSQL
MySQL
MongoDB
Redis
Disk
Memory
民間開(kāi)發(fā)的:
SQLServer
OrientDB
Oracle
Cassandra
關(guān)于Waterline的更多信息可以關(guān)注:
github:waterline
github:waterline-docs
在這一段我想不僅僅要談?wù)摰組odel層、View層和Controller層,我認(rèn)為還有必要談到Service層、和Policy層。
模型文件定義到/api/models中,由Waterline驅(qū)動(dòng),所有model都能全局訪(fǎng)問(wèn)。Sails提供命令行創(chuàng)建model的命令:$ sails generate model MODEL_NAME
實(shí)現(xiàn)在/views中,除了默認(rèn)提供的ejs模版引擎之外,還能更換成jade、handlebars等模版引擎
在/api/controller目錄里,Sails中提供創(chuàng)建controller的命令:$ sails generate controller CONTROLLER_NAME。Sails也提供同時(shí)創(chuàng)建model和對(duì)應(yīng)的Controller的命令:$ sails generate api API_NAME。
在/api/services目錄里,存放自定義的服務(wù),所有service都能夠全局訪(fǎng)問(wèn),Sails官方的建議是把邏輯處理都放在該層中,Controller層只做路由的分發(fā)和輕邏輯的處理。
在/api/policies目錄里,存放自定義的過(guò)濾器。該層是一條請(qǐng)求在到達(dá)Controller之前根據(jù)需求過(guò)濾請(qǐng)求的中間層。在/api/policies目錄中定義的文件,還需要在config/policies.js文件中為需求應(yīng)用到某一過(guò)濾器的Action配置。
路由Sails中要理解路由,首先要記得這個(gè)名詞blueprint,中文翻譯為:藍(lán)圖。我不知道官方是否解釋過(guò)為什么要用個(gè)單詞,但以我的理解,Sails的blueprint是負(fù)責(zé)指揮每一條客戶(hù)端請(qǐng)求應(yīng)該分配到服務(wù)器端的哪個(gè)Action去,所以叫藍(lán)圖吧。
blueprint主要分為三種:RESTful routes、Shortcut routes、Action routes。
當(dāng)路徑諸如:/:modelIdentity 或者 /:modelIdentity/:id的時(shí)候,blueprint會(huì)根據(jù)HTTP的動(dòng)作(GET、POST、DELETE、PUT等)來(lái)分配到相應(yīng)的Controller下相應(yīng)的Action來(lái)處理。例如一個(gè)POST請(qǐng)求/user會(huì)創(chuàng)建一個(gè)用戶(hù),一個(gè)DELETE請(qǐng)求/user/123會(huì)刪除id為123的用戶(hù)。
這種路由主要是方便開(kāi)發(fā),請(qǐng)求的參數(shù)可以直接寫(xiě)在請(qǐng)求路徑中,例如/user/create?name=joe會(huì)創(chuàng)建一個(gè)新的用戶(hù),/user/update/1?name=mike會(huì)更新id為1的用戶(hù)的名字。shortcut routes在開(kāi)發(fā)環(huán)境很便利,但是在生產(chǎn)環(huán)境下需要關(guān)閉。
這種路由會(huì)自動(dòng)的為Controller層的每一個(gè)Action創(chuàng)建一個(gè)路由,例如你的Controller層有一個(gè)FooController.js,里面有一個(gè)Actionbar,那么請(qǐng)求/foo/bar就會(huì)分配到barAction。
當(dāng)然Sails也會(huì)提供自定義的路由,用戶(hù)可以在config/routes.js和config/polices.js這兩個(gè)配置文件中選擇關(guān)閉或者打開(kāi)blueprint提供的路由,和定義自己的路由。
安全要確保產(chǎn)品的安全性,要對(duì)幾種常見(jiàn)的攻擊和安全策略了如指掌,諸如CORS、CSRF、DDOS、XSS等。Sails對(duì)于常見(jiàn)的安全策略都有提供支持,且只需要通過(guò)相關(guān)的配置文件就可以控制安全策略的等級(jí)。深入探討Web的安全策略,并不在本文的范疇內(nèi),日后我會(huì)以這個(gè)為題寫(xiě)一篇文章聊聊Web的安全。
想要了解更多Sails的安全策略可以看看這里:sails: security
Sails提供了一個(gè)全局對(duì)象sails.log用來(lái)處理日志信息的輸出,日志是分level的,在config/log.js中配置日志輸出的level,而level的作用看下表:
Priority | level | Log fns visible |
---|---|---|
0 | silent | N/A |
1 | error | .error() |
2 | warn | .warn(), .error() |
3 | debug | .debug(), .warn(), .error() |
4 | info | .info(), .debug(), .warn(), .error() |
5 | verbose | .verbose(), .info(), .debug(), .warn(), .error() |
6 | silly | .silly(), .verbose(), .info(), .debug(), .warn(), .error() |
Sails的日志管理默認(rèn)是info層的,既會(huì)輸出.info(), .debug(), .warn(), .error()的信息。
單元測(cè)試Sails使用了mocha進(jìn)行單元測(cè)試,在新建Sails項(xiàng)目的時(shí)候,沒(méi)有創(chuàng)建單元測(cè)試的文件夾,需要自己手動(dòng)構(gòu)造單元測(cè)試目錄,官方建議的目錄是這樣的:
. ├── api ├── assets ├── ... ├── test │ ├── unit │ │ ├── controllers │ │ │ └── UsersController.test.js │ │ ├── models │ │ │ └── Users.test.js │ │ └── ... │ ├── fixtures │ ├── ... │ ├── bootstrap.test.js │ └── mocha.opts └── views
而我在單元測(cè)試常用的組合是:mocha、should、supertest、?istanbul?
其中should是提供斷言,supertest是用于測(cè)試Controller層的時(shí)候偽造http請(qǐng)求的,而istanbul則是提供測(cè)試代碼覆蓋率的。
關(guān)于怎么在Sails中編寫(xiě)測(cè)試代碼,可以參考 sails:testing
對(duì)于有即時(shí)性通訊需求的Web應(yīng)用,我們會(huì)用Socket,Sails也為這方面提供了支持。在客戶(hù)端提供js文件:sails.io.js,而在服務(wù)器端提供全局對(duì)象:sails.sockets。通過(guò)這兩個(gè)對(duì)象,就可以進(jìn)行客戶(hù)端和服務(wù)器端即時(shí)性通訊的開(kāi)發(fā)了。
Sails默認(rèn)會(huì)啟動(dòng)WebSocket功能,在客戶(hù)端訪(fǎng)問(wèn)服務(wù)器端的時(shí)候,會(huì)自動(dòng)嘗試在同域名下連接socket。
值得注意的是,這樣會(huì)對(duì)AngularJS、EmberJS等前端MVVC開(kāi)發(fā)產(chǎn)生一些障礙。
比如進(jìn)行AngularJS開(kāi)發(fā)的時(shí)候,我們?cè)?b>http://localhost:9000跑AngularJS項(xiàng)目,而服務(wù)器端卻跑在http://localhost:1337。
當(dāng)訪(fǎng)問(wèn)http://localhost:9000的時(shí)候,sails.io.js會(huì)嘗試于當(dāng)前路徑下進(jìn)行socket連接,也就是http://localhost:9000,這時(shí)會(huì)出錯(cuò),因?yàn)榉?wù)器是跑在http://localhost:1337的。
在開(kāi)發(fā)的時(shí)候要解決這樣的問(wèn)題的時(shí)候,我們只需要在AngularJS這邊引入sails.io.js之后定義連接路徑就行了:
結(jié)語(yǔ)
可以說(shuō)Sails涵蓋了Web開(kāi)發(fā)中會(huì)遇到的絕大部分需求和問(wèn)題,如果深入研究Sails的話(huà),是受益匪淺的。
如果本文對(duì)您有用
請(qǐng)不要吝嗇你們的Follow與Start
這會(huì)大大支持我們繼續(xù)創(chuàng)作
「Github」
MZMonster :@MZMonster
JC_Huang :@JerryC8080
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78937.html
摘要:是下的一個(gè)優(yōu)秀的框架,但是使用后,在流量增長(zhǎng)時(shí),進(jìn)程有時(shí)突然內(nèi)存暴漲保持高占用。如果是內(nèi)存泄露引起的,則需要細(xì)心檢查代碼,確定變量能正常回收。每個(gè)對(duì)象有自己產(chǎn)生的內(nèi)存。譯注但是大對(duì)象內(nèi)存區(qū)本身不是可執(zhí)行的內(nèi)存區(qū)。 Sails.js 是 node 下的一個(gè)優(yōu)秀的 MVC 框架,但是使用 Sails 后,在流量增長(zhǎng)時(shí), node 進(jìn)程有時(shí)突然內(nèi)存暴漲、保持高占用。經(jīng)過(guò)翻閱源碼后,發(fā)現(xiàn)這個(gè)問(wèn)...
摘要:業(yè)務(wù)邏輯處理層,采用的的語(yǔ)法編寫(xiě)。配置層這層里面有和兩層,然后和一些。所以遇到這個(gè)情況就檢查是不是鏈接配的有問(wèn)題或者的服務(wù)已關(guān)閉。在瀏覽器輸入查出來(lái)的結(jié)果如圖所示這條數(shù)據(jù)手動(dòng)添加的,這樣一個(gè)很簡(jiǎn)單的算完成了。官網(wǎng)官網(wǎng)阮一峰模塊 showImg(https://segmentfault.com/img/remote/1460000010885716); 項(xiàng)目構(gòu)建 安裝Node就不多說(shuō)了,...
摘要:原文鏈接基于怎么設(shè)計(jì)用戶(hù)權(quán)限控制前言有人說(shuō),每個(gè)人都是平等的也有人說(shuō),人生來(lái)就是不平等的在人類(lèi)社會(huì)中,并沒(méi)有絕對(duì)的公平,一件事,并不是所有人都能去做一樣物,并不是所有人都能夠擁有。 原文鏈接:BlueSun | 基于RESTful API 怎么設(shè)計(jì)用戶(hù)權(quán)限控制? 前言 有人說(shuō),每個(gè)人都是平等的;也有人說(shuō),人生來(lái)就是不平等的;在人類(lèi)社會(huì)中,并沒(méi)有絕對(duì)的公平,一件事,并不是所有人都能去做;...
摘要:原文鏈接基于怎么設(shè)計(jì)用戶(hù)權(quán)限控制前言有人說(shuō),每個(gè)人都是平等的也有人說(shuō),人生來(lái)就是不平等的在人類(lèi)社會(huì)中,并沒(méi)有絕對(duì)的公平,一件事,并不是所有人都能去做一樣物,并不是所有人都能夠擁有。 原文鏈接:BlueSun | 基于RESTful API 怎么設(shè)計(jì)用戶(hù)權(quán)限控制? 前言 有人說(shuō),每個(gè)人都是平等的;也有人說(shuō),人生來(lái)就是不平等的;在人類(lèi)社會(huì)中,并沒(méi)有絕對(duì)的公平,一件事,并不是所有人都能去做;...
閱讀 579·2023-04-25 16:00
閱讀 1624·2019-08-26 13:54
閱讀 2503·2019-08-26 13:47
閱讀 3434·2019-08-26 13:39
閱讀 1052·2019-08-26 13:37
閱讀 2748·2019-08-26 10:21
閱讀 3544·2019-08-23 18:19
閱讀 1609·2019-08-23 18:02