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自定义角色与受权》