注意Roy Fielding关于REST设计的以下指南
5.2.1.1资源和资源标识符
REST中信息的关键抽象是资源。任何可以命名的信息都可以是资源:文档或图像、时间服务(例如“今天洛杉矶的天气”)、其他资源的集合、非虚拟对象(例如人)等等。换句话说,任何可能成为作者超文本引用目标的概念都必须符合资源的定义。
资源是到一组实体的概念映射,而不是在任何特定时间点对应于映射的实体。
更准确地说,资源R是一个随时间变化的隶属函数MR(t),对于时间t,它映射到一组等价的实体或值。集合中的值可以是资源表示和/或资源标识符。一个资源可以映射到空集合,空集合允许在一个概念的任何实现存在之前对该概念进行引用——在Web之前,这个概念对大多数超文本系统来说都是陌生的[61]。有些资源是静态的,在创建后的任何时候检查时,它们总是对应于相同的值集。其他人的价值随着时间的推移有很大程度的差异。
对于资源来说,唯一需要静态的是映射的语义学,因为语义学是区分一个资源和另一个资源的东西。
关键点已经用黑体标出,我在这一段的其余部分是为了说明上下文。
下面是一个场景。
我有一个web api,它有一个endpoint:http://www.myfakeapi.com/people
当客户端对此终结点执行GET请求时,它们会接收回人员列表。
Person
{
"Name": "John Doe",
"Age": "23",
"Favorite Color": "Green"
}
好吧,那很酷。
但是,如果我有一个“人”没有最喜欢的颜色,而我想像这样返回,这是否违反了REST设计实践和原则:
Person
{
"Name": "Bob Doe",
"Age": "23",
}
或者我应该这样回报他们:
Person
{
"Name": "Bob Doe",
"Age": "23",
"Favorite Color": null
}
问题是请求资源的客户端必须做额外的工作,以查看该属性是否首先存在。有些“Person”有自己喜欢的颜色,有些没有。如果“favorite Color”的json属性不存在,那么省略它们是否有违REST原则?还是应该为该属性指定一个“null”或空白值?
REST对此有何评论?我认为我应该返回null,而不是通过省略属性来更改客户机请求的资源的表示形式。
我们可以用各种方法来处理这个问题,这取决于用例,我只列出其中一种
1)首选枚举(仅当它对您的用例有意义时)
{
"Name": "Bob Doe",
"Age": "23",
"Favorite Color": NO_COLOR
}
当您在开始时知道属性的值时,请定义一组枚举常量,如果属性不适用于html" target="_blank">用户,请指定默认值。这有几个方面的帮助:
>
通过给出默认枚举常量,我们传达了从持久存储或可能从另一个远程服务中成功检索特定字段的值,但它具有默认值,因为该属性可能不适用于用户,或者用户对此属性没有任何值。
通过避免空模式,您的客户机代码将具有弹性,客户机可以为默认枚举常量准备代码。
当您开始为更多用户提供服务时,可能需要再添加一些枚举常量,这些常量可能不适用于您的每个客户机。当您添加他们不知道的新枚举时,他们可以在解析库中轻松地处理此问题,并根据客户机应用程序设计将其转换为其他内容。在Jackson中,我们可以使用反序列化功能。为此读取\u未知\u枚举值\u作为\u NULL。
2) 使用Null-不要为所有内容创建枚举常量
有些情况下,空对象是完全有效的。例如,在下面的示例中,如果没有常用引号,则使用null是有意义的。
{
"Name": "Bob Doe",
"Age": "23",
"Favorite Quote": null
}
3) 清楚地记录您所需的属性
如果在RESTAPI文档中使用swagger,则可以根据需要标记强制属性。未标记的是可选的。这样,客户机将准备好处理它们是否为NULL或空字符串。(它也应适用于其他API文档工具)
糟糕的做法:我注意到一些用户以这种方式编写代码,他们发送错误的响应模式与发送成功响应的模式相同。请回答这个问题
4)添加/修改属性(只要你没有违反与客户的合同)
假设以后添加了收藏夹颜色
属性,当前您正在向客户端发送以下响应。当您添加最喜爱的颜色时,您将向您的客户发布新合同,但是您的客户应该有故障保护代码,并且他们应该处理未知属性。在Jackson中,我们将使用反序列化功能。此属性的未知属性失败。非中断更改不一定需要v2。
Person
{
"Name": "Bob Doe",
"Age": "23",
}
当您开始设计API时,不需要忽略任何三个选项,所以您不需要在开始设计时忽略其余的三个选项。但是,您可能需要在以后添加一些属性(见#4),这是非常好的。
我想不出这会违反什么REST约束(如果您感兴趣,这里有一个简短概述的链接)。它也不会违反GET请求的幂等性。然而,这仍然是一种不好的做法。
API的使用者应该知道期望得到什么,理想情况下,这应该有很好的文档记录(我非常喜欢为此使用Swagger)。对预期内容的任何更改都应传达给消费者,可能以发行说明的形式。可能会破坏您的消费者的更改应该在新版本的API中交付。
因为你的Person1和Person2在技术上是不同的对象结构,所以这可能会打破它本身(让我们面对现实,我们并不总是发现作为开发人员的边缘情况)。你不只是想让你的API在一个基本的层面上工作,让最终用户见鬼去吧——你想在设计它的时候考虑到最终消费者,这样他们的生活就更容易了。
我正在使用GenericRequest(内置jsonrequest的扩展)对接收json对象并返回一个字符串的服务器进行REST调用,如果json对象已经存在,则为“0”,否则为非零字符串。 然而,使用下面的代码,无论我发送了什么,我总是得到一个“0”回来。 在Postman中进行测试时,给定输入,如:{“Email”:“DLEE23122”,“Password”:“1234”,“UserName
我需要刷新令牌,但HttpErrorResponse不会返回请求的结果。 收到http://127.0.0.1:8000/api/pdv返回响应:{“令牌错误”:“令牌已过期”} 但是,当我的令牌过期时,我会收到(跨源请求被阻止)。就这个案子。 这是我的配置 配置/cors我用的是barryvdh/laravel-cors 中间件组 我试图得到回应(console.log(error.error)
问题内容: 我正在运行以下MySQL查询,以查找没有手册(且车轮有黑轮等)的汽车 查询的结果看起来正确,但是它两次返回ID为27的汽车。如何更改查询,以使所有结果都是唯一的(没有重复项)? 问题答案: 假定这是唯一的主键,那么其中的一种联接将导致笛卡尔乘积。也就是说:或包含多个匹配项。 子查询通常是消除笛卡尔积的好工具。下面的示例查询显示了两种使用子查询的方法。 第一个子查询可确保我们只查看在20
为什么改变求和顺序会返回不同的结果? = Java和JavaScript都返回相同的结果。 我知道,由于浮点数在二进制中的表示方式,一些有理数(如1/3-0.333333...)不能精确表示。 为什么简单地改变元素的顺序会影响结果?
问题内容: 我正在使用HSM和PKCS11处理密钥派生问题,目前我无法理解为什么我会看到完全不同的结果,这取决于我是否使用generateKey()方法,而不是使用crypto()方法。在这两种情况下,我都尝试将DESede / ECB / NoPadding算法用于结果,但是根据我用来生成结果的方法(deriveKey与加密),我看到了不同的结果。 退后一会儿,以给出高层次的概述…我正在使用Gl
当我浏览包含使用headless选项的产品的页面时,我会得到不同的结果 对于同一个问题,一次我得到的结果没有排序,另一次得到的结果排序正确。 Selenium firefox浏览器: 根据这篇帖子: “firefox在使用headless选项时不会发送不同的标题”。 如何使用无头选项从刮擦中获得恒定的结果? 更新: 原来,广告弹出窗口隐藏了价格排序菜单。通过设置DebanjanB发布的恒定窗口大小