医生预约系统
作为一名病人,我想要从系统中得知指定日期内我熟悉的医生是否具有空闲时间,以便于我向该医生预约就诊。
医院开放了一个/appointmentService的 Web API,传入日期、医生姓名作为参数,可以得到该时间段该名医生的空闲时间,该 API 的一次 HTTP 调用如下所示:
POST /appointmentService?action=query HTTP/1.1
{date: "2020-03-04", doctor: "mjones"}
然后服务器会传回一个包含了所需信息的回应:
HTTP/1.1 200 OK
[
{start:"14:00", end: "14:50", doctor: "mjones"},
{start:"16:00", end: "16:50", doctor: "mjones"}
]
得到了医生空闲的结果后,我觉得 14:00 的时间比较合适,于是进行预约确认,并提交了我的基本信息:
POST /appointmentService?action=confirm HTTP/1.1
{
appointment: {date: "2020-03-04", start:"14:00", doctor: "mjones"},
patient: {name: icyfenix, age: 30, ……}
}
如果预约成功,那我能够收到一个预约成功的响应:
HTTP/1.1 200 OK
{
code: 0,
message: "Successful confirmation of appointment"
}
如果发生了问题,譬如有人在我前面抢先预约了,那么我会在响应中收到某种错误信息:
HTTP/1.1 200 OK
{
code: 1
message: "doctor not available"
}
到此,整个预约服务宣告完成
第 0 级是 RPC 的风格,如果需求永远不会变化,也不会增加,那它完全可以良好地工作下去。
我们可以吧医生的信息看做资源,每个资源存在一个id。通过拼接url来完成参数的命中:
POST /doctors/mjones HTTP/1.1
{date: "2020-03-04"}
然后服务器传回一组包含了 ID 信息的档期清单,注意,ID 是资源的唯一编号,有 ID 即代表“医生的档期”被视为一种资源:
HTTP/1.1 200 OK
[
{id: 1234, start:"14:00", end: "14:50", doctor: "mjones"},
{id: 5678, start:"16:00", end: "16:50", doctor: "mjones"}
]
我还是觉得 14:00 的时间比较合适,于是又进行预约确认,并提交了我的基本信息:
POST /schedules/1234 HTTP/1.1
{name: icyfenix, age: 30, ……}
比起第 0 级,第 1 级的特征是引入了资源,通过资源 ID 作为主要线索与服务交互,但第 1 级至少还有三个问题并没有解决:
正对于上面的三个问题提出解决方案:
按这个思路,获取医生档期,应采用具有查询语义的 GET 操作进行:
GET /doctors/mjones/schedule?date=2020-03-04&status=open HTTP/1.1
HTTP/1.1 200 OK
[
{id: 1234, start:"14:00", end: "14:50", doctor: "mjones"},
{id: 5678, start:"16:00", end: "16:50", doctor: "mjones"}
]
我仍然觉得 14:00 的时间比较合适,于是又进行预约确认,并提交了我的基本信息,用以创建预约,这是符合 POST 的语义的:
POST /schedules/1234 HTTP/1.1
{name: icyfenix, age: 30, ……}
如果预约成功,那我能够收到一个预约成功的响应:
HTTP/1.1 201 Created
Successful confirmation of appointment
如果发生了问题,譬如有人在我前面抢先预约了,那么我会在响应中收到某种错误信息:
HTTP/1.1 409 Conflict
doctor not available
在第二问中我们直接定死了 /schedules/1234 即通过这个url就可以访问指定id下的资源,可以进一步解耦,将这个 url的后缀也存在起来,进而解耦方便修改。
GET /doctors/mjones/schedule?date=2020-03-04&status=open HTTP/1.1
HTTP/1.1 200 OK
{
schedules:[
{
id: 1234, start:"14:00", end: "14:50", doctor: "mjones",
links: [
{rel: "comfirm schedule", href: "/schedules/1234"}
]
},
{
id: 5678, start:"16:00", end: "16:50", doctor: "mjones",
links: [
{rel: "comfirm schedule", href: "/schedules/5678"}
]
}
],
links: [
{rel: "doctor info", href: "/doctors/mjones/info"}
]
}