假设我有一个名为Appointment
的实体。该实体代表一个Doctor
和一个Patient
之间的医疗预约。
要创建一个新的Appointment
,我发送了一些类似以下内容的内容:
POST /appointments
{
"doctorId": 98173821,
"patientId": 2138212,
... omitted for brevity
}
效果很好。
如您所见,此对象与其他两个资源(Patient
和Doctor
(嵌套在一起
想象一下,登录Patient
(使用他的 JWT 令牌(想要查看他的Appointments
历史记录。
今天,我这样做,向以下地址发送请求:
GET /patients/2138212/appointments?page=1&size=2&startDate=2019-01-01&endDate=2019-08-01
(请随时批评(
由于这是历史记录,因此无需检索整个Appointment
对象。响应仅检索有关Appointments
的基本信息。响应如下所示:
{
"timestamp": 1566216359,
"transactionId": "6eed92831cad128",
"data": {
"appointments": [
{
"id": 6372,
"doctorId": 98173821,
"date": "2019-01-01"
},
{
"id": 6985,
"doctorId": 98173821,
"date": "2019-02-01"
}
]
}
}
现在,如果Patient
在前端选择特定Appointment
并且需要显示有关此特定Appointment
的详细信息,该怎么办?对这样的 REST 端点进行建模的最佳方式是什么?
我的选择:
GET /patients/2138212/appointments/6372
GET /appointments/6372
第一个看起来不错,并跟踪嵌套资源上的 REST 模式,因为可以表示Appointment
6372 属于Patient
2138212。
第二个不提供可读性。我的意思是,查看资源,我不知道谁拥有这个Appointment
.这就是为什么我更喜欢第一种方法。
现在,沿着这条路走下去,Doctor
也必须看到他的任命历史。
今天,我这样做,向以下地址发送请求:
GET /doctors/98173821/appointments?page=1&size=2&startDate=2019-01-01&endDate=2019-08-01
(请随时批评(
响应如下所示:
{
"timestamp": 1566216359,
"transactionId": "6eed92831cad321",
"data": {
"appointments": [
{
"id": 6372,
"patientId": 2138212,
"date": "2019-01-01"
},
{
"id": 6985,
"patientId": 2138212,
"date": "2019-02-01"
}
]
}
}
现在,如果Doctor
在前端选择特定Appointment
并且需要显示有关此特定Appointment
的详细信息,该怎么办?对这样的 REST 端点进行建模的最佳方式是什么?
我的选择:
GET /doctors/98173821/appointments/6372
GET /appointments/6372
我的问题:
- 如何表示具有"两个所有者"的嵌套资源?在这个问题上,我指出有比这更好的方法吗?
- 对于
Appointments
的历史,有人建议我做/appointments/doctors/{doctorId}
和/appointments/patients/{patientId}
,我非常不同意,因为Doctor
和Patient
拥有Appointment
,而不是相反。你有什么建议?
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
对于约会的历史,有人建议我做/约会/医生/{doctorId}和/约会/患者/{patientId},我非常不同意,因为医生和患者拥有约会,而不是相反。你有什么建议?
URI 中路径段的层次结构不必意味着"所有权"。 同样,从 REST 客户端的角度来看,/X/Y
和/X/Y/Z
之间没有关系 - 它们是不同的标识符,因此是不同的资源。
两者之间没有根本区别
/appointments/patients/{patientId}
/patients/{patientId}/appointments
我们通常更喜欢后者,不是因为它本身"更好",而是因为当使用相对引用来标识相对于该资源标识符层次结构的位置时,它可以更方便。
/appointments/patients/{patientId} + .. -> /appointments/patients
/patients/{patientId}/appointments + .. -> /patients/{patientId}