API设计:缓存"部分"嵌套对象

Mic*_*ick 7 rest api-design data-structures reactjs redux

假设我们的学校有一些数据,包括姓名和学生名单,以及有一些数据的学生,包括他们注册的课程和他们学校的参考.在客户端:

  • 我想显示一个显示学校信息的屏幕,其中包括所有学生的名单.
  • 我想显示一个显示学生信息的屏幕,包括他们学校的名称和他们正在学习的课程名称.
  • 我想缓存此信息,以便我可以显示相同的屏幕而无需等待新的提取.我应该能够从学校到学生再回到学校而不再去学校.
  • 我想显示每个屏幕只有一个提取.从学校页面到学生页面可以单独获取,但我应该能够在一次获取中向学校显示学生姓名的完整列表.
  • 我想避免重复数据,这样如果学校名称发生变化,一次更新学校将导致在学校页面和学生页面上显示正确的名称.

是否有一个很好的方法来完成所有这些,或者是否必须解除一些限制?

第一种方法是使用API​​执行以下操作:

GET /school/1

{
    id: 1,
    name: "Jefferson High",
    students: [
        {
             id: 1
             name: "Joel Kim"
        },
        {
             id: 2,
             name: "Chris Green"
        }
        ...
    ]
}


GET /student/1

{
    id: 1,
    name: "Joel Kim",
    school: {
        id: 1,
        name: "Jefferson High"
    }
    courses: [
        {
             id: 3
             name: "Algebra 1"
        },
        {
             id: 5,
             name: "World History"
        }
        ...
    ]
}
Run Code Online (Sandbox Code Playgroud)

这种方法的一个优点是,对于每个屏幕,我们只需要进行一次获取.在客户端,我们可以规范学校和学生,以便他们互相引用ID,然后将对象存储在不同的数据存储中.但是,student嵌套在其中的对象school不是完整对象 - 它不包括嵌套课程,也不包括返回学校的引用.同样,school里面的对象student没有所有参加学生的列表.在数据存储中存储对象的部分表示将导致客户端上的一堆复杂逻辑.

我们可以为学校和学生存储嵌套的部分对象,而不是规范化这些对象.然而,这意味着数据重复 - Jefferson High的每个学生都会将学校的名称嵌套.如果在为特定学生取得学校名称之前更改了学校名称,那么我们将为该学生显示正确的学校名称,但在其他地方显示错误的名称,包括在"学校详细信息"页面上.

另一种方法可能是设计API以仅返回嵌套对象的id:

GET /school/1

{
    id: 1,
    name: "Jefferson High",
    students: [1, 2]
}


GET /student/1

{
    id: 1,
    name: "Joel Kim",
    school: 1,
    courses: [3, 5]
}
Run Code Online (Sandbox Code Playgroud)

我们总是对所有引用的对象进行"完整"表示,因此将这些信息存储在数据存储客户端非常容易.但是,这需要多次提取才能显示每个屏幕.为了显示学生的信息,我们必须取得学生,然后取回他们的学校,以及他们的课程.

是否有更智能的方法可以让我们只缓存每个对象的一个​​副本,并防止多个提取显示基本屏幕?

Rob*_*gam 4

您可能会混合两个概念:存储表示。您可以返回非标准化表示(您建议的第一个选项),而无需将这些“部分”对象存储在数据库中。

因此,我建议尝试返回非标准化表示,但将它们标准化存储(如果您使用的是关系数据库)。

另外,还有一个改进建议:您可能希望在表示中使用正确的 URI 而不是 Id。您可能希望客户端知道从“哪里”获取该对象,因此只提供 URI 会更容易。否则,客户端需要弄清楚如何从 Id 中生成 URI,而这通常最终会在客户端中进行硬编码,这在 REST 中是禁忌。