Json 表示RESTAPI中有两个不同类型(实体)所有者的嵌套资源的最佳方法?

Json 表示RESTAPI中有两个不同类型(实体)所有者的嵌套资源的最佳方法?,json,rest,api,Json,Rest,Api,假设我有一个名为约会的实体。此实体表示一名医生和一名患者之间的医疗预约 要创建一个新的约会,我发送了如下内容: 职位/约会 { "doctorId": 98173821, "patientId": 2138212, ... omitted for brevity } 效果很好 如您所见,此对象与其他两个资源嵌套(Patient和Doctor) 假设登录的患者(使用他的JWT令牌)想要查看他的预约历史记录 今天,我向以下人员发送请求: GET/patients/2138212/预约?

假设我有一个名为
约会
的实体。此实体表示一名
医生
和一名
患者
之间的医疗预约

要创建一个新的
约会
,我发送了如下内容:

职位/约会

{
  "doctorId": 98173821,
  "patientId": 2138212,
  ... omitted for brevity
}
效果很好

如您所见,此对象与其他两个资源嵌套(
Patient
Doctor

假设登录的
患者(使用他的JWT令牌)想要查看他的
预约历史记录

今天,我向以下人员发送请求:

GET/patients/2138212/预约?第1页和第2页&起始日期=2019-01-01和结束日期=2019-08-01

(请随意批评)

由于这是一个历史记录,因此无需检索整个
Appointment
对象。响应仅检索有关约会的基本信息。响应如下所示:

{
  "timestamp": 1566216359,
  "transactionId": "6eed92831cad128",
  "data": {
    "appointments": [
      {
        "id": 6372,
        "doctorId": 98173821,
        "date": "2019-01-01"
      },
      {
        "id": 6985,
        "doctorId": 98173821,
        "date": "2019-02-01"
      }
    ]
  }
}
{
  "timestamp": 1566216359,
  "transactionId": "6eed92831cad321",
  "data": {
    "appointments": [
      {
        "id": 6372,
        "patientId": 2138212,
        "date": "2019-01-01"
      },
      {
        "id": 6985,
        "patientId": 2138212,
        "date": "2019-02-01"
      }
    ]
  }
}
现在,如果
患者
在前端选择一个特定的
预约
,并且需要显示该特定的
预约
的详细信息,该怎么办?像这样对REST端点建模的最佳方法是什么

我的选择:

  • GET/patients/2138212/预约/6372
  • GET/约会/6372
第一个看起来不错,并在嵌套资源上跟进休息模式,因为它可以表示
预约
6372属于
患者
2138212

第二个不提供可读性。我的意思是,看看资源,我不知道谁拥有这个
约会
。这就是为什么我喜欢第一种方法

现在,沿着这条路走下去,
医生也必须查看他的预约历史

今天,我向以下人员发送请求:

GET/doctors/98173821/预约?第1页和第2页&开始日期=2019-01-01和结束日期=2019-08-01

(请随意批评)

响应如下所示:

{
  "timestamp": 1566216359,
  "transactionId": "6eed92831cad128",
  "data": {
    "appointments": [
      {
        "id": 6372,
        "doctorId": 98173821,
        "date": "2019-01-01"
      },
      {
        "id": 6985,
        "doctorId": 98173821,
        "date": "2019-02-01"
      }
    ]
  }
}
{
  "timestamp": 1566216359,
  "transactionId": "6eed92831cad321",
  "data": {
    "appointments": [
      {
        "id": 6372,
        "patientId": 2138212,
        "date": "2019-01-01"
      },
      {
        "id": 6985,
        "patientId": 2138212,
        "date": "2019-02-01"
      }
    ]
  }
}
现在,如果
医生
在前端选择一个特定的
预约
,并且需要显示该特定的
预约
的详细信息,该怎么办?像这样对REST端点建模的最佳方法是什么

我的选择:

  • GET/doctors/98173821/appointment/6372
  • GET/约会/6372
我的问题是:

  • 如何表示具有“两个所有者”的嵌套资源?在这个问题上,还有比我指出的更好的方法吗
  • 关于
    预约的历史
    ,有人建议我做
    /预约/医生/{doctorId}
    /预约/病人/{patientId}
    ,我非常不同意,因为
    医生和
    病人拥有
    预约
    不是相反的。你有什么建议

  • REST不关心资源标识符的拼写

    GET /patients/2138212/appointments/6372
    GET /appointments/6372
    GET /5877971d-4f91-4297-9995-94f560190463
    
    这三种拼写都很好。从REST客户机的角度来看,URI只是一个不透明的字节序列,可以用作缓存键

    为URI选择拼写很像为变量名选择拼写——机器不在乎;你可以选择任何你喜欢的拼写,这很方便

    此外,REST并不特别关心如何将域模型组织到资源(也称为“文档”)中。“医生对预约6372的看法”不一定与“患者对预约6372的看法”相同;这里有权衡考虑。

    例如:

    https://stackoverflow.com/questions/57557129/best-way-to-represent-nested-resources-that-has-two-different-type-entities-ow
    https://api.stackexchange.com/2.2/questions/57557129?order=desc&sort=activity&site=stackoverflow
    
    关于预约的历史,有人建议我做/Appointment/doctorId}和/Appointment/patients/{patientId},我非常不同意,因为医生和患者拥有预约,而不是相反。你有什么建议

    URI中路径段的层次结构不一定意味着“所有权”。同样,从REST客户端的角度来看,
    /X/Y
    /X/Y/Z
    之间没有关系——它们是不同的标识符,因此是不同的资源

    两者之间没有根本区别

    /appointments/patients/{patientId}
    /patients/{patientId}/appointments
    
    我们通常更喜欢后者,不是因为它本身“更好”,而是因为当使用相对引用来标识另一个相对于此资源标识符层次结构位置的资源标识符层次结构时,它会更方便

    /appointments/patients/{patientId} + .. -> /appointments/patients
    /patients/{patientId}/appointments + .. -> /patients/{patientId}
    

    关于使用哪种URI样式的问题通常主要是基于观点的,因此与主题无关。其次,URI本身是指向资源的指针,客户端不应试图从URI推断任何语义。服务器可以通过链接关系名称提示客户使用这样的URI。此外,嵌套子资源可能看起来很棒,因为所有数据都可以在一个响应中设置,尽管您基本上绕过了这些子资源的缓存。理想情况下,您只需向客户机提供指向各自约会的链接,如果感兴趣,客户机可以调用这些链接