我是REST的新手。我帮助在工作中实现了一些名为REST的东西,但它打破了很多规则,很难将它作为REST来限定。我想遵循HATEOAS指南,剩下的问题是关于媒体类型及其规范的文档。即,当一种媒体类型确实是另一种媒体类型的扩展时。
例如,我已经决定使用'application / hal + json'作为基本媒体类型。用户将收到的所有内容都将是带有一些添加字段的HAL blob。我不想把我的媒体类型称为'application / hal + json',在我看来应该有更多的信息可用,但我希望它清楚这是除了额外的字段之外它们是什么这是我的数据。此外,我的系统最终将继承一些这些字段,例如请求(不是HAL blob)和响应格式。通用“用户”类型可能只有用户ID和名称,例如“学生”或“教师”等扩展名会有不同的附加字段。
在媒体类型本身的某处代表此扩展是否有意义?人们通常会在他们的HATEOAS文档链接中记录这种关系吗?如果是这样,这里的总体趋势是什么?我希望我的API易于使用,因此应该遵循可用的规范。
答案 0 :(得分:1)
我想指出您转向真正的RESTful架构的一些事情。
首先,RESTful API必须执行内容协商。说你的基本类型是hal + json似乎很奇怪。听起来你想拥有像parent + hal + json或者hal + json这样的类型; type = parent。这意味着你的客户必须特别理解这些类型......这不是非常RESTful,因为它只是一个本地实现。这在现实世界中很好。你可以做到这一点......几乎每个人都做这样的事情。
要成为真正的RESTful api,您必须为其他内容类型提供类似的支持......这可能会变得混乱。
现在专门针对HAL,您可以使用两种方式,以便您的客户可以发现"他们正在获取什么数据类型。一个是CURIEs,另一个是个人资料http://tools.ietf.org/html/draft-kelly-json-hal-06#section-5.6我认为个人资料更像是你在此之后所做的事情,因为它允许你记录将要检索的资源的约定和约束。
但不要算过CURIE的。那里已经有很多定义的语义。您的模型可能适合http://schema.org套之一,然后您可以使用他们的链接关系,客户应该知道发生了什么。
如果您真的希望对资源的语义进行大量控制......您可能希望用它来查看http://json-ld.org/ @context概念将是一个很好的参考。
在我看来,这是一个非常薄的例子,特别是对于HAL。我还没有看到一个客户端足够聪明,可以在运行时解析和关注语义。我认为重要的是当有人在构建客户时,信息可用,他们可以发现学生是一个人。有一天构建客户端的东西将是客户端生成器代码,它将使用该信息为您构建一个不错的客户端对象模型。
TL; DR,如果你坚持使用HAL,请使用CURIE和Profiles来获得你想要的东西。
答案 1 :(得分:-1)
这个问题是一个非常开放的讨论,它实际上取决于不同的工程师如何解释REST标准和最佳实践。尽管如此,作为一名具有足够REST服务开发经验的软件工程师(并且专业地面对同样的问题),我会在这里添加我的输入。
REST服务开发规则严重依赖于url定义。以这样一种方式暴露您的api非常重要,这样您的客户就可以通过查看网址定义来准确了解每个api发生的情况。
话虽如此,不同的客户(以及不同的工程师)以不同的方式查看最佳实践。例如,如果您尝试通过电子邮件搜索用户,则至少有两种方法
1)
GET /users/emails/{email}
//客户可以将其解释为 “通过电子邮件获取用户”2)
而“通过电子邮件搜索用户”GET /users?email={email}
//客户可以将其解释为 因查询参数3)
GET /users/email={email}
//这可以解释为#1
这取决于开发人员他们希望如何公开此API以及他们如何为客户端记录它。从不同的角度来看,所有方法都是正确的。
现在针对您的问题。这是我的方法在“User
”,“Student
”和“Teacher
”方面的样子。
我将这3个中的每一个视为单独的资源?为什么?因为它们是分开的类型,即使它们中的2个从第3个扩展。现在我的apis怎么样?
学生:
1)检索学生列表:
GET /students
2)检索ID为
的学生GET /students/{id}
3)创建学生:POST
/students
4)更新学生:PUT
/students/{id}
5)删除学生:删除
/students/{id}
6)搜索学生:GET
/students?{whateverQueryParamsYouWantForSearch}
同样适用于教师。
现在这里是User
。
1)
GET /users
:检索所有用户的列表(Students
和Teachers
)2)
GET /users?type={type}
:这是踢球者。你可以指定 键入是学生或老师,您将返回特定的数据 类型(适当记录的课程)3)
POST /users?type={type}
:创建特定的用户类型 (student
或teacher
)
..等等。
主要区别在于:具有根URL /users
的api可用于两种类型的用户(前提是始终指定类型并向客户端记录)。虽然Student
和Teacher
api特定于这些类型。
我的钱一直是特定类型,而搜索的通用类型(意味着搜索两种类型的用户..使用/users?params
)。这是客户了解正在发生的事情的最简单方法。即使记录它们也要容易得多。
最后谈论HATEOAS。是的,它是标准的一部分,最佳实践是始终提供您要返回的资源的URL /链接,或者如果您的返回对象很复杂并且包含可能包含可能通过apis暴露的资源的其他资源。例如,
/users?type=student&email=abc@abc.com
将返回所有使用该电子邮件的用户,最好在此处关注HATEOAS,并为每个返回的用户提供一个网址,以便网址如下:/students/{id}
。这就是我们正常处理HATEOAS的方式
这就是我要添加的全部内容。正如我先前所说,这是一个非常开放的讨论。每个工程师都以不同的方式解释标准,没有一种方法可以处理所有的用例。有一些基本规则,如果您遵循它们,客户和其他开发人员会为您鼓掌:)