我对设计REST API有疑问。考虑以下情况:我们有一个名为banners
的表和一个名为images
的表。每个横幅都有一个图像,每个图像属于一个横幅(表格图像用于存储另一个图像,而不仅仅是横幅,因此加入表格不是解决方案)。
table Banner table Images
________________________ ______________________
| id | Int | | id | Int |
| title | VARCHAR | | filename | VARCHAR|
|__________|___________| | banner_id | Int |
| article_id| Int |
|___________|________|
我已经阅读了一些关于创建REST API的文章,根据它们,我应该为数据检索创建这个URI:
1) api/banner/1
2) api/banner/1/image
但是我总是需要带横幅的图像,那么为什么不通过调用第一个API路径来返回所有内容呢?如果我这样做(两条路线),我应该如何实现前端的调用呢?我应该首先编写两个http.get()
方法来检索横幅,然后再搜索相关图像吗?谢谢你的回答!
答案 0 :(得分:1)
在这种情况下,您可以选择几种方法:
如您所述,如果您同时提供这两种资源,则必须执行两次GET请求才能检索所需的所有数据。
您可以同时执行这两项工作 - api/banner/1/image
可以返回有关图片的数据,api/banner/1
可以返回有关横幅的数据,并嵌入图片。
如果您使用HAL等媒体类型,则会将其视为“嵌入式”媒体类型。资源:
{
"id": 1,
"title": "banner title",
"_embedded": {
"image" : {
"id": 1,
"filename": "some path",
"_links": {
"self": {
"href": "api/banner/1/image"
}
}
}
},
"_links": {
"self": {
"href": "/api/banner/1"
}
}
}
通过这种方式,您可以使用单个GET
获取所需的所有数据。
没有规则说您的数据库表必须与您的API资源完全对齐。
仅提供api/banner/1
并让它返回类似内容没有错:
{
"id": 1,
"title": "banner title",
"imageFileName": "some path"
}
您碰巧将数据字段存储在系统内部的单独表中这一事实只是一个实现细节/
虽然您目前专注于GET方法,但您的资源结构还应考虑您要提供的非GET方法,这意味着您应该考虑其他操作,例如创建,更新和删除。这将有助于确定提供上述哪种操作 - 例如
您提到图像可能用于其他类型的图像,但横幅只能有一个图像。如果是这种情况,我建议改变关系的方向,例如:
table Banner table Images
________________________ ______________________
| id | Int | | id | Int |
| title | VARCHAR | | filename | VARCHAR|
| image_id | Int | |___________|________|
|__________|___________|
否则,如果Image表中的两个记录具有相同的banner_id,您将如何处理?
答案 1 :(得分:0)
您的API网址结构永远不应代表真正的数据库结构。如果切换到(例如)像mongodb这样的nosql数据库,数据库结构将会非常不同。
此外,您的数据库结构不是最佳的。您的图片表不应该知道消费者(banner_id
,articel_id
稍后comment_id
?)。
保持简单:
调用api/banner/1
将返回在客户端显示横幅所需的所有数据。