json-server关系查询(_embed和_expand)
json-server关系
官方指正
参考博文1: json-server的关系图谱详解(Relationships)
参考博文2: json-server全攻略
不过两篇博文都没提到关于 posts
和 comments
等名字的重点,一定要注意英语语法中单词的复数形式!!!!
需求
在使用 json-server 模拟数据时,因为项目需求(商店后台管理系统),既要获取商品的分类,又要获取详细的商品数据。因为老师讲解的案例是使用的搭建好的 swagger 的接口,所以分别请求对应的 api 就可以拿到想要的数据,而一开始我模仿此数据类型而写的 json 数据结构为:
{
"inventory":[
{
"id": 1,
"class": "饮品",
"item": [
{
"id": 10230,
"name": "农夫山泉"
}
]
}
],
}
使用 apifox 模拟请求时无法对更下一级的数据进行精准查询和操作,所以这个写法肯定行不通。
当时百度苦苦没有结果,都想要放弃 JSON 而去使用 PHP + MySql 了。
当然,我也没有忘记去官网查文档,有一个叫做 Relationships 的,中文翻译叫做关系
官方文档中译.png
然后去搜索网上的前辈们的博客,自然是找到了相对应的案例(还是找了很久),内容很详细,讲解很清晰。
使用
第一步
首先是数据结构,写成如下
{
"inventories": [
{
"id": 1,
"title": "饮品",
"enTitle": "drinks"
},
{
"id": 2,
"title": "调味品",
"enTitle": "condiments"
}
],
"stocks":[
{
"id": 1230980,
"name": "农夫山泉",
"amount": 10,
"origin": "四川 成都 武侯区",
"buyPrice": 1,
"weight": 550,
"productionDate": "2022-01-01",
"shelfLife": 12,
"image": null,
"inventoryId": 1
}
],
}
这里 inventory 是总分类,stock 是分类下所有商品,两者之间的关联属性是 inventoryId
- _embed 包含子资源
请求语句为http://localhost:3004/inventories/1?_embad=stocks
。我这里的 json-server 端口为 3004。意思从 inventory 中根据 id 为 1 的选项去 stock 中匹配查询,并合并到 inventory 的查询结果中。
查询结果如下:
{
"id": 1,
"title": "饮品",
"enTitle": "drinks",
"stocks": [
{
"id": 1,
"name": "农夫山泉",
"amount": 10,
"origin": "四川 成都 武侯区",
"buyPrice": 1,
"weight": 550,
"productionDate": "2022-01-01",
"shelfLife": 12,
"image": null,
"inventoryId": 1
}
]
}
- _expand 包含父资源
请求语句为http://localhost:3004/stocks/1230980?_expand=inventory
。意思是查询 stock 某商品,并根据分类 id 去 inventory 中匹配查询,将查询结果合并在 stock 的结果中。
查询结果如下:
{
"id": 1,
"name": "农夫山泉",
"amount": 10,
"origin": "四川 成都 武侯区",
"buyPrice": 1,
"weight": 550,
"productionDate": "2022-01-01",
"shelfLife": 12,
"image": null,
"inventoryId": 1,
"inventory": {
"id": 1,
"title": "饮品",
"enTitle": "drinks"
}
}
-
/inventories/1/stocks
直接根据 inventory 中的为 1 的 id,去 stock 中查询匹配关系的数据
查询结果如下:
[
{
"id": 1,
"name": "农夫山泉",
"amount": 10,
"origin": "四川 成都 武侯区",
"buyPrice": 1,
"weight": 550,
"productionDate": "2022-01-01",
"shelfLife": 12,
"image": null,
"inventoryId": 1
}
]
名字总结
我踩了一个大坑,没错,就是表名。这涉及到了英语的复数语法,我在取名时将 inventory
直接简单粗暴地在后面加了个 s,这导致我只能从inventorys
中查询到 stocks
中的数据,而不能从 stocks
溯源 inventorys
。
而将 inventorys
改成 inventories
后,尽管你 stocks
中关联的属性名叫做 inventoryId
和 _expand=inventory
,同样能够查询到对应的数据。
所以英语还是要学好滴O(∩_∩)O哈哈~
使用总结
第一步:创建好两个表,一定要注意复数名字,然后在表明为子资源的数据中加上 父资源的英文的单数形式 拼上 Id
第二步:根据需要查询。_embed
和 直接查询下级不需要注意名字,_expand
的参数则需要使用为英文单词的单数形式。
语法结构简单,但功能很强大。