REST API - 设计考虑

4
我有一个有关设计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() 方法来分别检索横幅和相关图片?谢谢回答!
2个回答

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方法,但资源结构也应考虑您想要提供的非GET方法,这意味着您应考虑其他操作,例如创建、更新和删除。这将有助于确定要提供哪些操作,例如:

  1. 您是否曾经创建过没有图像的横幅?
    1. 如果是,则应同时提供两个资源。但是,如果存在图像资源,则仍然可以嵌入图像资源以节省第二个GET请求。
    2. 如果不是,则没有问题,只需提供横幅资源-从客户端的角度来看,他们永远不应考虑没有图像的横幅。
  2. 您多久更新一次图像而不更新横幅的其他属性?
    1. 如果答案是频繁地更新,则提供图像资源可能会有所帮助-但同样,您仍然可以嵌入资源以节省第二个GET请求。

关于您的数据结构的建议

您提到该图片可能用于其他类型的图片,但横幅只能有一张图片。如果是这样的话,我建议反转关系方向,例如:
table Banner                    table Images
________________________        ______________________
| id       | Int       |        | id        | Int    |
| title    | VARCHAR   |        | filename  | VARCHAR|
| image_id | Int       |        |___________|________|
|__________|___________|

否则,如果Image表中有两条记录具有相同的banner_id,您将如何处理?

谢谢您的精彩文章 :-) 它帮助我澄清了关于REST API的困惑 :) - ketysek

0

你的API URL结构不应该代表真实的数据库结构。如果你切换到(例如)像mongodb这样的nosql数据库,数据库结构会非常不同。

此外,你的数据库结构并不是最优的。你的图片表不应该知道消费者(banner_idarticel_id后来是comment_id?)。

保持简单:调用api/banner/1将返回在客户端显示横幅所需的所有数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接