RESTFul媒体类型继承

时间:2014-07-20 22:06:08

标签: rest hateoas media-type

我是REST的新手。我帮助在工作中实现了一些名为REST的东西,但它打破了很多规则,很难将它作为REST来限定。我想遵循HATEOAS指南,剩下的问题是关于媒体类型及其规范的文档。即,当一种媒体类型确实是另一种媒体类型的扩展时。

例如,我已经决定使用'application / hal + json'作为基本媒体类型。用户将收到的所有内容都将是带有一些添加字段的HAL blob。我不想把我的媒体类型称为'application / hal + json',在我看来应该有更多的信息可用,但我希望它清楚这是除了额外的字段之外它们是什么这是我的数据。此外,我的系统最终将继承一些这些字段,例如请求(不是HAL blob)和响应格式。通用“用户”类型可能只有用户ID和名称,例如“学生”或“教师”等扩展名会有不同的附加字段。

在媒体类型本身的某处代表此扩展是否有意义?人们通常会在他们的HATEOAS文档链接中记录这种关系吗?如果是这样,这里的总体趋势是什么?我希望我的API易于使用,因此应该遵循可用的规范。

2 个答案:

答案 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}:创建特定的用户类型   (studentteacher

..等等。

主要区别在于:具有根URL /users的api可用于两种类型的用户(前提是始终指定类型并向客户端记录)。虽然StudentTeacher api特定于这些类型。

我的钱一直是特定类型,而搜索的通用类型(意味着搜索两种类型的用户..使用/users?params)。这是客户了解正在发生的事情的最简单方法。即使记录它们也要容易得多。

最后谈论HATEOAS。是的,它是标准的一部分,最佳实践是始终提供您要返回的资源的URL /链接,或者如果您的返回对象很复杂并且包含可能包含可能通过apis暴露的资源的其他资源。例如,

/users?type=student&email=abc@abc.com

将返回所有使用该电子邮件的用户,最好在此处关注HATEOAS,并为每个返回的用户提供一个网址,以便网址如下:/students/{id}。这就是我们正常处理HATEOAS的方式

这就是我要添加的全部内容。正如我先前所说,这是一个非常开放的讨论。每个工程师都以不同的方式解释标准,没有一种方法可以处理所有的用例。有一些基本规则,如果您遵循它们,客户和其他开发人员会为您鼓掌:)