这一章我们深入一下业务逻辑,将数据模型间的关系捋一捋,在创建关系之前,我先将我的结构屡一下,核心模型有3个
Customer 用户,一个用户可以有多个清单
checklist 清单,一个清单只属于一个用户,可以有多个物品
item 物品,一个物品只属于一个用户
理清楚关系后,我们来通过loopback relation来创建关系
一、创建关系
打开终端,进入loopback应用根目录,输入lb relation
lb relation
1、创建用户和清单的关系
创建用户拥有多个清单的关系
选择从中创建关系的模型: Customer
关系类型: has many
选择与之创建关系的模型: checklist
输入关系的属性名称: checklists
输入定制外键: customerId
需要直通模型? No
允许在 REST API 中嵌套关系: No
禁止包含关系: No
创建清单属于用户的关系
选择从中创建关系的模型: checklist
关系类型: belongs to
选择与之创建关系的模型: Customer
输入关系的属性名称: customer
输入定制外键: customerId
允许在 REST API 中嵌套关系: No
禁止包含关系: No
2、创建用户和物品的关系
创建用户拥有多个物品的关系
选择从中创建关系的模型: Customer
关系类型: has many
选择与之创建关系的模型: item
输入关系的属性名称: items
输入定制外键: customerId
需要直通模型? No
允许在 REST API 中嵌套关系: No
禁止包含关系: No
创建物品属于用户的关系
选择从中创建关系的模型: item
关系类型: belongs to
选择与之创建关系的模型: Customer
输入关系的属性名称: customer
输入定制外键: customerId
允许在 REST API 中嵌套关系: No
禁止包含关系: No
3、创建清单和物品的关系
创建清单拥有多个物品的关系
选择从中创建关系的模型: checklist
关系类型: has many
选择与之创建关系的模型: item
输入关系的属性名称: items
输入定制外键:
需要直通模型? No
允许在 REST API 中嵌套关系: No
禁止包含关系: No
创建物品属于清单的关系
选择从中创建关系的模型: item
关系类型: belongs to
选择与之创建关系的模型: checklist
输入关系的属性名称: checklist
输入定制外键:
允许在 REST API 中嵌套关系: No
禁止包含关系: No
二、添加时间戳
npm install loopback-ds-timestamp-mixin --save
很多时候我们需要知道用户是什么时候添加的数据,找了个时间戳组件,如上安装,打开文件
server/model-config.json
添加刚刚安装的时间戳组件调用地址
"mixins": [ "loopback/common/mixins", "loopback/server/mixins", "../node_modules/loopback-ds-timestamp-mixin", "../common/mixins", "./mixins" ]
然后在需要加时间戳的数据模型里,加上时间戳
这里我的应用里涉及到了checklist.json和item.json两个数据模型
打开文件在properties下面加上mixins即可
"properties": { ... }, "mixins": { "TimeStamp": true },
三、测试添加接口
重启loopback服务,打开浏览器,输入http://localhost:3000/explorer,先登录获取到用户id和token后,将token在右上角设置后
1、添加清单
展开checklist,POST一条记录,customerId就是用户id,填入刚刚登录账号的用户id
{
"title": "学习清单",
"customerId": "6253d205970c51bc2ca4bccb"
}
数据返回如下,nice~~ 时间戳加上去了
{
"title": "学习清单",
"id": "6253e138baa312ca67575aca",
"createdAt": "2022-04-11T08:05:12.942Z",
"updatedAt": "2022-04-11T08:05:12.942Z",
"customerId": "6253d205970c51bc2ca4bccb"
}
2、添加物品
展开item,POST一条记录,checklistId填入刚刚添加成功的checklist的id
{
"name": "铅笔",
"type": "item",
"checked": false,
"checklistId": "6253e138baa312ca67575aca"
}
数据返回如下,一切顺利,就很棒~
{
"name": "铅笔",
"type": "item",
"checked": false,
"id": "6253e421c2be5acbba7980e8",
"checklistId": "6253dc8bafcb1ac77fc273d6",
"createdAt": "2022-04-11T08:17:37.425Z",
"updatedAt": "2022-04-11T08:17:37.425Z"
}
四、配置数据模型的读写权限
现在我们来进一步配置清单的读写权限,之前的配置中,清单的读权限是全部开放的,而实际的业务逻辑是,用户只能看到自己创建的清单,只能修改自己创建的清单,这样配置更符合逻辑,我们给清单,打开终端
lb acl
配置读权限
选择要应用 ACL 条目的模型: checklist
选择 ACL 作用域: 所有方法和属性
选择访问类型: 读取
选择角色 拥有该对象的用户
选择要应用的许可权 明确授权访问
配置写权限
选择要应用 ACL 条目的模型: checklist
选择 ACL 作用域: 所有方法和属性
选择访问类型: 写入
选择角色 拥有该对象的用户
选择要应用的许可权 明确授权访问
同理,item数据模型也是一样的配置,只有物品的所有者才可以有读写权限
五、最终测试
1、在loopback中再注册一个用户,通过两个用户创建清单和物品
2、测试POST checklist,POST item,分别通过两个账号,添加清单和物品(前面都介绍过了,这里就不细讲了)
3、测试GET读写权限
由于权限设置时,将checklist和item的读取权限都设置为了数据拥有者才可以读取
GET /checklists
GET /items
因此,这两个接口已经无法获取到数据了
现在只可以查询属于当前登录账号的数据了
GET /checklists/{id}
用户登录后,打开对应{id}的接口,输入第二步创建的checklist的id,如果id是当前用户创建的则返回结果,如果不是当前用户创建的则返回401表示未授权,item的权限同checklist是一样的。
写权限和读权限差不多,对应接口为PUT和DELETE,大家可以自行测试一下。
4、对于关系使用的小贴士
loopback还有一个很有用的关系包含方法,分享给大家,由于之前在创建关系的时候选择了不禁用包含关系,在Customer查询checklist的接口中,输入对应当前账户的用户id,在filter里输入包含关系,如下
{"include":["items"]}
返回的结果会包含当前用户下的所有checklist,并包含checklist关联的所有item,个人感觉很有用,具体要看前端的实际调用情况。
[
{
"title": "学习清单",
"id": "6253f7d4a51043d659ad88cc",
"createdAt": "2022-04-11T09:41:40.082Z",
"updatedAt": "2022-04-11T09:41:40.082Z",
"customerId": "6253d205970c51bc2ca4bccb",
"items": [
{
"name": "铅笔",
"type": "item",
"checked": false,
"id": "6253f804a51043d659ad88cd",
"checklistId": "6253f7d4a51043d659ad88cc",
"customerId": "6253d205970c51bc2ca4bccb",
"createdAt": "2022-04-11T09:42:28.815Z",
"updatedAt": "2022-04-11T09:42:28.815Z"
},
{
"name": "橡皮",
"type": "item",
"checked": false,
"id": "6253f80fa51043d659ad88ce",
"checklistId": "6253f7d4a51043d659ad88cc",
"customerId": "6253d205970c51bc2ca4bccb",
"createdAt": "2022-04-11T09:42:39.561Z",
"updatedAt": "2022-04-11T09:42:39.561Z"
}
]
}
]
好了,关于loopback涉及到的基础知识和应用,全部写完了,再深入的学习就要在实际应用中再去发现了,希望这几篇关于loopback的文章能帮到正在做接口的猴们,希望疫情早点结束,希望可以下楼,希望可以吃上烧烤,呜呜呜~~~