HTTP: API Design: Dealing with Relationship

 24th April 2021 at 5:07pm

当 model 与其他 model 有关系存在时,如何用 RESTful API 表达?有这几种情况:

  • 一对一,比如一个人的姓名对其生日
  • 一对多,比如专辑对歌曲,某一歌曲仅属于一个专辑
  • 多对多,比如帖子对标签,一个帖子可以有多个标签,一个标签也可以有多个帖子

一对一没有太多可讲,容易设计。一对多及多对多比较复杂。

一对多

比如专辑对歌曲的例子。

{
    "album_name": "Undun",
    "artist": "The Roots",
    "tracks": [
        89,
        90,
        91,
        ...
    ]
}
{
    "album_name": "Undun",
    "artist": "The Roots",
    "tracks": [
        {"id": 89, "order": 1, "title": "Public Service Announcement", "duration": 245},
        {"id": 90, "order": 2, "title": "What More Can I Say", "duration": 264},
        {"id": 91, "order": 3, "title": "Encore", "duration": 159},
        ...
    ],
}

区别在于,对于 tracks 字段,第一个方案显示的是其 ID,第二个显示的是其内容。哪一种更好呢?我会认为是第一种。因为无论客户端是 browser 还是 app,客户端侧都会有对基础数据(比如 tracks)的一份缓存,而 tracks 会有其单独的 API 进行查询。此时最好遵循 single source of truth,即 tracks 的数据都在其单独的 API 进行查询,而不在 album 的回包中直接显示。当然这会增加额外的请求量,但也避免了数据不一致(比如新旧区别)造成的问题。