REST API - 设计考虑因素

时间:2016-11-05 14:22:04

标签: rest

我对设计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 个答案:

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

  1. 您是否创建过没有图像的横幅
    1. 如果你这样做,你应该提供这两种资源。但是如果存在,你仍然可以嵌入图像资源,以保存第二个GET请求。
    2. 如果你没有,那么只提供横幅资源没问题 - 从客户的角度来看,他们不应该考虑没有图像的横幅
  2. 在不更新横幅的其他属性的情况下,您多久更新一次图像?
    1. 如果答案频繁,那么提供图像资源可能会有所帮助 - 但同样,您仍然可以嵌入资源以保存第二个GET请求
  3. 对您的数据结构的建议

    您提到图像可能用于其他类型的图像,但横幅只能有一个图像。如果是这种情况,我建议改变关系的方向,例如:

    table Banner                    table Images
    ________________________        ______________________
    | id       | Int       |        | id        | Int    |
    | title    | VARCHAR   |        | filename  | VARCHAR|
    | image_id | Int       |        |___________|________|
    |__________|___________|
    

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

答案 1 :(得分:0)

您的API网址结构永远不应代表真正的数据库结构。如果切换到(例如)像mongodb这样的nosql数据库,数据库结构将会非常不同。

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

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