【问题标题】:Writing a REST API for Complex Nested Data为复杂的嵌套数据编写 REST API
【发布时间】:2014-07-20 09:54:35
【问题描述】:

所以,我正在 Angular 中构建一个应用程序,该应用程序将在后面利用 REST API,在 Node.js 上运行。在设计此 API 时,我在处理数据复杂性时遇到了一些麻烦,我需要一些帮助。

这里有不同的资源,有问题。

  1. 医生(每个医生可能有多名患者)
  2. 患者(每个患者可能有多个医生)
  3. 预约(自然而然,医生有预约)
  4. 提醒(提醒可以从医生发送给患者,而不是反过来)

现在,这里是应用程序可能执行的一些操作,因此 API 的要求很明确。

  1. 每位医生都必须能够请求他的所有患者或特定患者。
  2. 每位患者都必须能够请求其所有医生或特定医生。
  3. 每位医生都必须能够请求他在特定日期或所有日期(如有必要)的所有预约(看所有患者)。
  4. 每位患者都必须能够在特定日期或所有日期(如有必要)请求所有预约(看所有医生)。
  5. 每位医生都必须能够请求一位患者的所有预约。
  6. 每位患者都必须能够请求一位医生为其所有预约。
  7. 每位医生都必须能够请求对特定患者的所有提醒。

请记住,请求自然可以是 POST、GET、DELETE 或 PUT。现在,这就是我目前所处的位置。我只提到 URL,发送 POST、GET、DELETE 或 PUT 时对每个 URL 的操作是不言自明的。

  1. /doctors/
  2. /doctors/:id
  3. /doctors/:id/patients(返回/patient/:id的列表)
  4. /doctors/:id/appointments
  5. /patients/
  6. /patients/:id
  7. /patients/:id/doctors(返回/doctors/:id的列表)
  8. /patients/:id/appointments

现在,我对上面的那些没问题。这是我的问题。

  1. 如何在没有像/doctors/:id/patients/:id/appointments 这样的嵌套的情况下为任务编号 7 设计 URL?
  2. 此外,我可以通过上述方法轻松获得医生或患者的所有预约。具体的约会呢? /doctors/:id/appointments/:id/patients/:id/appointments/:id 感觉不太对。
  3. 另外,如何预约看特定患者或特定医生?
  4. 那么每个医生或患者在特定日期的预约情况如何?

我觉得嵌套太多了。请帮忙。

【问题讨论】:

    标签: node.js rest express


    【解决方案1】:

    您的端点列表看起来不错。我猜你问的问题可能会有不同的意见。

    以下是我对可以做什么的看法:

    如何为任务编号 7 设计一个 URL,而无需像 /doctors/:id/patients/:id/appointments 这样的嵌套?

    我假设会存在一个提醒集合并将其定义如下:

    /doctors/:doctorid/reminders
    /doctors/:doctorid/reminders/:patientid
    

    此外,我可以很容易地通过上述方式为医生或患者预约所有的时间。特定的约会呢? /doctors/:id/appointments/:id 或 /patients/:id/appointments/:id 感觉不太对。

    没有必要将端点复杂化到那个级别。如果您已经知道预约 ID,为什么还要通过医生或患者端点来访问它?没关系,你直接通过它的collection来获取item。

    /appointments/:appointmentid
    

    另外,预约看特定患者或特定医生的情况如何?

    您可以利用查询参数的强大功能来处理这类事情。并非所有内容都是 URL 模板的一部分。可以将过滤特定记录之类的功能添加到查询参数中。比如

    /doctors/:doctorid/appointments?pantientName=
    /patients/:patientid/appointments?doctorName=
    

    那么每个医生或患者在特定日期的预约呢?

    同样的事情,你可以这样:

    /patients/:patientid/appointments?from=&to
    

    或者为非常知名的案例设置特殊端点,例如我今天、本周、本月的约会:

    /patients/:patientid/appointments/:year
    /patients/:patientid/appointments/:year/:month
    /patients/:patientid/appointments/:year/:month/:day
    

    后者实际上可以重用用于实现在一系列日期之间进行约会的相同逻辑。

    【讨论】:

    • 我想这正是我想要的。谢谢!
    【解决方案2】:

    URI 结构不是 REST 问题,因为根据统一接口约束,它必须与客户端分离。

    重要的是:

    • 特定的 URI(包括路径和查询)只能识别单个资源。
    • URI 映射到资源而不是操作,因此如果您使用人类可读的漂亮 URI,那么它们将只包含名词。

    如何在没有嵌套的情况下为任务编号 7 设计 URL /doctors/:id/patients/:id/appointments?

    您可以映射减少现有约会集合,如下所示:

    • /appointments?doctor=1&patient=1
    • /appointments/doctor:1/patient:1

    那么对于每个医生或患者的特定预约呢? 日期?

    您可以使用日期过滤器来做到这一点:

    • /appointments?date=2014-09-02
    • /appointments/date:2014-09-02

    【讨论】:

    • 感谢您的回答。一个问题。关系方法是否不需要我维护另一个具有关系的集合,当然链接到 Doctor 和 Patient 集合中的相应文档?这将在查询数据库时添加另一个原子操作。而且我不知道这与性能有何关系。
    • 不,正如我所说,您的 REST 接口的结构可能与您的数据库结构完全不同。 Ofc 如果要存储有关关系的其他数据,则必须更改数据库结构,但如果不是,则可以保留当前的查询和数据库结构。 REST 只是一种表示(或交付方法),它与数据库没有任何联系。至少在设计良好的应用程序中不是这样。我想您应该阅读有关端口和适配器以及其他以域为中心的软件架构解决方案的信息。
    • 我想我开始明白了。我一直为 CRUD 操作建模一个非常简单的 REST API。这可能解释了我为什么要考虑数据库。您能否详细说明一下在 Express 中如何处理像 /doctorPatientRelationship/:relationshipId 这样的路由,而不需要另一个集合来存储 relationshipId,好吗?
    • 例如,如果你想删除一段关系,你会怎么做? DELETE /doctor/:id/patient/:id 可能意味着删除关系并从数据库中删除患者...... DELETE /relations/:rid 可能只意味着一件事。 “一条路线中是否有多个参数,RESTful?”我从来没有听说过否认这一点的规则,所以是的。
    • 顺便说一句。以这种方式描述 n:m 关系不是我自己的想法,也许看这个会有所帮助:youtube.com/… 通过设计你的 api。
    猜你喜欢
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    • 2011-10-29
    • 2016-04-11
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    相关资源
    最近更新 更多