LoopBack是一個高度可擴展的開源Node.js框架,它使您可以以不多的編碼或不編寫任何代碼來建立動態的端到端REST API。mongodb
LoopBack 框架是由一組 Node.js 的模塊構成的。你能夠單獨使用這些模塊或把它們組合在一塊兒使用。 應用經過 LoopBack model API 可使用如下三種方式訪問數據。數據庫
應用程序經過 LoopBack model API 用以上三種方式查詢數據,儲存數據,上傳文件,發送 email, 推送消息,註冊/登錄用戶等遠程或本地的服務。用戶也能夠經過 Strong Remoting 將後端的 API 經過 REST, WebSocket(或其餘傳輸協議)供客戶端調用。npm
這是官方給出的一個關於咖啡店點評的示例。json
咖啡店點評是一個網站,咱們能夠用來發布咖啡店的評論。有三個數據模型:後端
它們有以下關係:api
通常來講,用戶能夠建立,編輯,刪除和閱讀咖啡店的評論,並經過 ACLs 指定基本規則和權限:瀏覽器
在 nodejs 環境下安裝 Loopback CLI 工具。bash
npm install -g loopback-cli
複製代碼
安裝成功後,輸入 lb -help 查看 Loopback CLI 工具的命令:服務器
lb -help
Available commands:
lb acl
lb app
lb bluemix
lb boot-script
lb datasource
lb export-api-def
lb middleware
lb model
lb oracle
lb property
lb relation
lb remote-method
lb soap
lb swagger
lb zosconnectee
複製代碼
在命令行輸入:
lb
複製代碼
回車後按照提示輸入項目名稱,其餘選擇回車。
? 您的應用程序的名稱是什麼? CoffeeShop
? 輸入目錄名稱以包含項目: CoffeeShop
create CoffeeShop/
info 將工做目錄更改成 CoffeeShop
? 您想要使用哪一個版本的 LoopBack? 3.x (Active Long Term Support)
? 您想要什麼種類的應用程序? api-server (使用本地用戶認證的 LoopBack API 服務器)
正在生成 .yo-rc.json
複製代碼
安裝成功後按照提示操做後續步驟:
後續步驟:
將目錄更改成您的應用程序
$ cd CoffeeShop
在應用程序中建立模型
$ lb model
運行應用程序
$ node .
複製代碼
進入項目根目錄,運行應用程序。
node .
hsts deprecated The "includeSubdomains" parameter is deprecated. Use "includeSubDomains" (with a capital D) instead. node_modules/loopback/lib/server-app.js:74:25
Web server listening at: http://localhost:3000
Browse your REST API at http://localhost:3000/explorer
複製代碼
打開瀏覽器,輸入上面提示的地址能夠訪問 LoopBack 的 API 接口測試頁面。因爲咱們尚未建立任何模型,因此只能在頁面上看到框架自帶的 user 的 API 調用接口。
在項目根目錄命令行經過 control+C 退出服務。
LoopBack 能夠自動鏈接市面上絕大多數數據源。咱們一 MongoDb 爲例來爲項目添加數據持久化庫。
lb datasource
? 輸入數據源名稱: md
? 爲 md 選擇鏈接器: MongoDB (StrongLoop 支持)
? Connection String url to override other settings (eg: mongodb://username:password@hostname:port/da
tabase):
? host: localhost
? port: 27017
? user:
? password: [hidden]
? database: cshop
? 安裝 loopback-connector-mongodb@^4.0.0 Yes
+ loopback-connector-mongodb@4.2.0
added 7 packages from 11 contributors in 2.342s
複製代碼
首先,必須保證開發環境有 MongoDB 數據庫並已經啓動,數據庫不須要實現建立,框架會根據輸入的數據庫名稱自動建立。因爲 MongoDB 的鏈接插件沒有安裝,因此這裏選擇 Yes 來安裝。
在項目目錄的 server 子目錄下有以下文件:
server % tree
.
├── boot
│ ├── authentication.js
│ └── root.js
├── component-config.json
├── config.json
├── datasources.json
├── middleware.development.json
├── middleware.json
├── model-config.json
└── server.js
複製代碼
其中,datasources.json
是數據源的配置文件,咱們在代碼編輯器中打開這個文件,會看到咱們建立的 md 數據源。
{
"db": {
"name": "db",
"connector": "memory"
},
"md": {
"host": "localhost",
"port": 27017,
"url": "",
"database": "cshop",
"password": "",
"name": "md",
"user": "",
"connector": "mongodb"
}
}
複製代碼
因爲框架原先定義了一個數據源 db,咱們不須要了,把 db 數據源刪掉,將 md 數據源更名爲 db。修改以後代碼以下:
{
"db": {
"host": "localhost",
"port": 27017,
"url": "",
"database": "cshop",
"password": "",
"name": "md",
"user": "",
"connector": "mongodb"
}
}
複製代碼
建立好數據源,框架幫咱們自動鏈接數據庫,咱們對數據的持久化操做也會自動保存到數據庫中。
屬性名 | 屬性類型 | 是否必填 |
---|---|---|
name | String | y |
city | String | y |
lb model
? 請輸入模型名稱: CoffeeShop
? 選擇要向其附加 CoffeeShop 的數據源: db (mongodb)
? 選擇模型的基類 PersistedModel
? 經過 REST API 公開 CoffeeShop? Yes
? 定製複數形式(用於構建 REST URL):
? 公共模型或僅服務器? 公共
如今添加一些 CoffeeShop 屬性。
在完成時輸入空的屬性名稱。
? 屬性名稱: name
? 屬性類型: string
? 是否爲必需? Yes
? 缺省值[對於無,保留爲空白]:
下面添加另外一個 CoffeeShop 屬性。
在完成時輸入空的屬性名稱。
? 屬性名稱: city
? 屬性類型: string
? 是否爲必需? Yes
? 缺省值[對於無,保留爲空白]:
下面添加另外一個 CoffeeShop 屬性。
在完成時輸入空的屬性名稱。
? 屬性名稱
複製代碼
屬性名 | 屬性類型 | 是否必填 |
---|---|---|
date | date | y |
rating | number | n |
comments | string | y |
lb model
? 請輸入模型名稱: Review
? 選擇要向其附加 Review 的數據源: db (mongodb)
? 選擇模型的基類 PersistedModel
? 經過 REST API 公開 Review? Yes
? 定製複數形式(用於構建 REST URL):
? 公共模型或僅服務器? 公共
如今添加一些 Review 屬性。
在完成時輸入空的屬性名稱。
? 屬性名稱: date
? 屬性類型: date
? 是否爲必需? Yes
? 缺省值[對於無,保留爲空白]:
下面添加另外一個 Review 屬性。
在完成時輸入空的屬性名稱。
? 屬性名稱: rating
? 屬性類型: number
? 是否爲必需? No
? 缺省值[對於無,保留爲空白]:
下面添加另外一個 Review 屬性。
在完成時輸入空的屬性名稱。
? 屬性名稱: comments
? 屬性類型: string
? 是否爲必需? Yes
? 缺省值[對於無,保留爲空白]:
下面添加另外一個 Review 屬性。
在完成時輸入空的屬性名稱。
? 屬性名稱:
複製代碼
reviewer 模型繼承自框架自帶的 user 模型。在選擇模型的基類時不能選擇 PersistedModel
,而要選擇 user
,不用添加任何屬性,直接回車便可。
lb model
? 請輸入模型名稱: Reviewer
? 選擇要向其附加 Reviewer 的數據源: db (mongodb)
? 選擇模型的基類 User
? 經過 REST API 公開 Reviewer? Yes
? 定製複數形式(用於構建 REST URL):
? 公共模型或僅服務器? 公共
如今添加一些 Reviewer 屬性。
在完成時輸入空的屬性名稱。
? 屬性名稱:
複製代碼
在項目根目錄命令行經過 node . 來啓動服務。在瀏覽器中再次打開 http://localhost:3000/explorer。
能夠看到 API 調試界面除了先前的 user 接口外,增長了咱們剛剛建立的 3 個模型的接口。
LoopBack 支持許多不一樣類型的模型關係:BelongsTo, HasMany, HasManyThrough, and HasAndBelongsToMany 等等。根據項目需求能夠定義以下關係:
HasMany
reviewHasMany
reviewerBelongsTo
CoffeeShopBelongsTo
reviewerHasMany
reviewCoffeeShop 擁有多個 review,沒有中間模型和外鍵。
lb relation
? 選擇從中建立關係的模型: CoffeeShop
? 關係類型: has many
? 選擇與之建立關係的模型: Review
? 輸入關係的屬性名稱: reviews
? (可選)輸入定製外鍵:
? 須要直通模型? No
? 容許在 REST API 中嵌套關係: No
? 禁止包含關係: No
複製代碼
CoffeeShop 擁有多個 reviewer,沒有中間模型和外鍵。
lb relation
? 選擇從中建立關係的模型: CoffeeShop
? 關係類型: has many
? 選擇與之建立關係的模型: Reviewer
? 輸入關係的屬性名稱: reviewers
? (可選)輸入定製外鍵:
? 須要直通模型? No
? 容許在 REST API 中嵌套關係: No
? 禁止包含關係: No
複製代碼
review 屬於一個 CoffeeShop,沒有中間模型和外鍵。
lb relation
? 選擇從中建立關係的模型: Review
? 關係類型: belongs to
? 選擇與之建立關係的模型: CoffeeShop
? 輸入關係的屬性名稱: coffeeShop
? (可選)輸入定製外鍵:
? 容許在 REST API 中嵌套關係: No
? 禁止包含關係: No
複製代碼
review 屬於一個 reviewer,外鍵是 publisherId
,沒有中間模型。
lb relation
? 選擇從中建立關係的模型: Review
? 關係類型: belongs to
? 選擇與之建立關係的模型: Reviewer
? 輸入關係的屬性名稱: reviewer
? (可選)輸入定製外鍵: publisherId
? 容許在 REST API 中嵌套關係: No
? 禁止包含關係: No
複製代碼
reviewer 擁有多個 review,外鍵是 publisherId,沒有中間模型。
lb relation
? 選擇從中建立關係的模型: Reviewer
? 關係類型: has many
? 選擇與之建立關係的模型: Review
? 輸入關係的屬性名稱: reviews
? (可選)輸入定製外鍵: publisherId
? 須要直通模型? No
? 容許在 REST API 中嵌套關係: No
? 禁止包含關係: No
複製代碼
咱們在項目根目錄的 common 子目錄的 model 目錄下能夠看到咱們建立的與模型相關的 6 個文件:
common % tree
.
└── models
├── coffee-shop.js
├── coffee-shop.json
├── review.js
├── review.json
├── reviewer.js
└── reviewer.json
複製代碼
在 coffee-shop.json 文件中定義的關係:
"relations": {
"reviews": {
"type": "hasMany",
"model": "Review",
"foreignKey": ""
},
"reviewers": {
"type": "hasMany",
"model": "Reviewer",
"foreignKey": ""
}
},
複製代碼
在review.json
文件中定義的關係:
"relations": {
"coffeeShop": {
"type": "belongsTo",
"model": "CoffeeShop",
"foreignKey": ""
},
"reviewer": {
"type": "belongsTo",
"model": "Reviewer",
"foreignKey": "publisherId"
}
},
複製代碼
在reviewer.json
文件中定義的關係:
"relations": {
"reviews": {
"type": "hasMany",
"model": "Review",
"foreignKey": "publisherId"
}
},
複製代碼
loopback 應用經過模型訪問數據,所以控制對數據的訪問意味着對模型進行權限的控制:也就是說,指定什麼角色能夠在模型上執行讀取和寫入數據的方法。loopback 權限控制由權限控制列表或 ACL 決定。
根據項目需求,權限控制應執行如下規則:
任何人均可以閱讀評論。可是建立、編輯和刪除的操做必須在登陸以後纔有權限。 任何人均可以註冊爲用戶,能夠登陸和登出。 登陸用戶能夠建立新的評論,編輯或刪除本身的評論。然而,他們不能修改咖啡店的評論。
首先,拒絕全部人操做全部接口,這一般是定義 ACL 的起點,由於您能夠選擇性地容許特定操做的訪問。
lb acl
? 選擇要應用 ACL 條目的模型: (全部現有模型)
? 選擇 ACL 做用域: 全部方法和屬性
? 選擇訪問類型: 所有(匹配全部類型)
? 選擇角色 全部用戶
? 選擇要應用的許可權 明確拒絕訪問
複製代碼
如今容許全部人對 reviews 進行讀操做。
lb acl
? 選擇要應用 ACL 條目的模型: Review
? 選擇 ACL 做用域: 全部方法和屬性
? 選擇訪問類型: 讀取
? 選擇角色 全部用戶
? 選擇要應用的許可權 明確受權訪問
複製代碼
容許經過身份驗證的用戶對 coffeeshops 進行讀操做,也就是說,已登陸的用戶能夠瀏覽全部咖啡店。
lb acl
? 選擇要應用 ACL 條目的模型: CoffeeShop
? 選擇 ACL 做用域: 全部方法和屬性
? 選擇訪問類型: 讀取
? 選擇角色 任何已認證的用戶
? 選擇要應用的許可權 明確受權訪問
複製代碼
容許通過身份驗證的用戶對 reviews 進行建立操做,也就是說,已登陸的用戶能夠添加一條評論。
lb acl
? 選擇要應用 ACL 條目的模型: Review
? 選擇 ACL 做用域: 單個方法
? 輸入方法名稱 create
? 選擇角色 任何已認證的用戶
? 選擇要應用的許可權 明確受權訪問
複製代碼
使 review 的做者有權限(其「全部者」)對其進行任何更改。
lb acl
? 選擇要應用 ACL 條目的模型: Review
? 選擇 ACL 做用域: 全部方法和屬性
? 選擇訪問類型: 寫入
? 選擇角色 擁有該對象的用戶
? 選擇要應用的許可權 明確受權訪問
複製代碼
咱們須要用戶在添加評論時,自動填充日期字段的內容爲當前的日期。同時,因爲評論和評論者之間是經過publisherId
這個外鍵進行關聯的,用戶在添加評論時,須要將評論者的用戶 Id 做爲其內容進行填充。
咱們將定義一個遠程鉤子,每當在 Review 模型上調用 create()方法時(在建立新的評論時),它將被調用。
一般,咱們能夠定義兩種遠程鉤子:
beforeRemote()
在遠程方法以前運行。afterRemote()
在遠程方法以後運行。在這兩種狀況下,有兩個參數能夠供咱們使用:一個與要鉤子函數的遠程方法匹配的字符串,和一個回調函數。
這裏,咱們將在 review 模型中定義一個遠程鉤子,具體來講是 Review.beforeRemote。
修改 common/models/review.js:
module.exports = function(Review) {
Review.beforeRemote('create', function(context, user, next) {
context.args.data.date = Date.now();
context.args.data.publisherId = context.req.accessToken.userId;
next();
});
};
複製代碼
在建立 Review 模型的新實例以前調用此函數。
如何對 coffeeshops 的數據進行管理呢?這是咱們常說的後臺管理,須要一個管理員admin
的角色來承擔。 這部份內容將經過另一篇文章進行介紹。 《LoopBack3.0自定義角色與受權》