我有一个名为Columns的集合资源。一个GET
Accept: application/json
can't directly return a collection,所以我的代表需要将其嵌套在一个属性中: -
{ "propertyName": [
{ "Id": "Column1", "Description": "Description 1" },
{ "Id": "Column2", "Description": "Description 2" }
]
}
问题:
用于上述标识符 propertyName 的最佳名称是什么?应该是:
application/json
的使用的歧义作为媒体类型)NB我觉得应该有一些包装它的东西很舒服,正如@tuespetre指出的那样,XML或任何其他表示方式会迫使你将它包装到某种程度
当回放内容时,是否应该保留所述属性中的相同包装[鉴于出于安全原因它实际上并不是必需的,并且可能传统的JSON使用惯用法可能会丢弃这样的嵌套用于PUT和POST,因为它们是“没有必要防范脚本攻击”?
我的直觉告诉我它应该是对称的,因为每个其他的表示,但可能有先前的艺术放弃 d / *结果** [假设这是答案第1部分* *
...或者PUT-back(或POST)是否需要包装属性,只需使用: -
[ { "Id": "Column1", "Description": "Description 1" }, { "Id": "Column2", "Description": "Description 2" } ]
编辑:我特别感兴趣的答案是基于合理的理由,特别考虑到JSON对客户端使用的影响。例如,HAL负责定义对两个目标表示都有意义的绑定。
编辑2:还没有接受,为什么?到目前为止,答案没有引用或任何使他们在我搜索和挑选前20个点击中的东西突出的东西看似合理。我太挑剔了吗?我想我是(或者更有可能我不能正确地提出问题:D)。它有点疯狂,一周和3天,即使有一个公认的微不足道的奖金仍然只能获得123次观看(其中3个答案也不错)
答案 0 :(得分:3)
解决你的问题(而不是在我的原始答案中略微相切:D),这是我的观点:
1)我对此的主要看法是我不喜欢d
。作为使用API的客户端,我会发现它令人困惑。无论如何它甚至代表什么?数据?
其他选项看起来不错。 Columns
很好,因为它会向用户反映他们所要求的内容。
如果您正在进行分页,那么另一个选项可能是page
或slice
,因为它向客户明确表示他们没有收到集合的全部内容。
{
"offset": 0,
"limit": 100,
"page" : [
...
]
}
2)TBH,我不认为这会给你带来多大的改变,不过如果是我的话,我可能不会费心收回信封,因为我没有&#39 ;认为有任何需要(见下文)以及为什么要求结构比它需要的更复杂?
我认为回信封将是奇怪的。 POST应该允许你将项目添加到集合中,那么为什么客户需要发布信封才能执行此操作?
从RESTful的角度来看,将信封放回去是有意义的,因为它可以被视为更新与整个集合相关的元数据。我认为值得思考一下你将在信封中公开的那种元数据。我认为所有适合这个信封的东西(如分页,聚合,搜索方面和类似的元数据)都是只读的,所以客户端将其发送回服务器是没有意义的。如果您发现自己在信封中有大量数据,客户端能够变异 - 那么它可能是一个标志,将该数据分解为一个单独的资源,列表作为子集合。垃圾的例子:
/animals
{
"farmName": "farm",
"paging": {},
"animals": [
...
]
}
可以分解为:
/farm/1
{
"id": 1,
"farmName": "farm"
}
和
/farm/1/animals
{
"paging": {},
"animals": [
...
]
}
注意:即使进行了这种拆分,您仍然可以使用Facebook's或LinkedIn's字段扩展语法等方式将两者合并为单个响应。例如。 http://example.com/api/farm/1?field=animals.offset(0).limit(10)
作为回应,关于客户端应该如何知道他们正在POST和PUTing的JSON有效负载应该是什么样的问题 - 这应该反映在您的API文档中。我不确定是否有更好的工具,但Swagger提供的规范允许您使用JSON Schema记录您的请求正文应该是什么样子 - 请查看{{3} }如何定义模式,this page如何将它们作为body
类型的参数引用。不幸的是,Swagger还没有将请求主体可视化为它的花哨网页用户界面,但它是开源的,所以你总是可以添加一些东西来做到这一点。
在该页面的讨论主题中查看this page评论 - 他建议一种完全避免利用漏洞的方法,这意味着您可以安全地在响应的根目录中使用JSON数组,然后您不必担心你们两个问题。
您链接的漏洞使用Cookie来依赖您的API来验证用户的会话 - 只需使用查询字符串参数即可删除漏洞。无论如何,这可能值得这样做,因为在API上使用Cookie进行身份验证并不是非常RESTful - 您的某些客户可能不是Web浏览器,可能不想处理Cookie。
漏洞攻击是一种CSRF攻击形式,它依赖于攻击者能够在他/她自己的页面上向您的API上的敏感资源添加script
标记。
<script src="http://mysite.com/api/columns"></script>
受害者网络浏览器会将mysite.com
下存储的所有Cookie发送到您的服务器和服务器,这看起来像是合法请求 - 您将检查session_id
Cookie(或任何服务器端)框架调用cookie)并查看用户是否经过身份验证。请求将如下所示:
GET http://mysite.com/api/columns
Cookie: session_id=123456789;
如果您更改API而忽略Cookie并使用session_id查询字符串参数,攻击者将无法欺骗受害者网络浏览器将session_id发送到您的API。
现在,有效请求将如下所示:
GET http://mysite.com/api/columns?session_id=123456789
如果使用JavaScript客户端发出上述请求,您可以从cookie获取session_id。使用其他域中的JavaScript的攻击者将无法执行此操作,因为您无法获取其他域的Cookie( William's )。
现在我们已修复此问题并忽略了session_id cookie,攻击者网站上的脚本标记仍会发送类似的请求,其中包含以下GET行:
GET http://mysite.com/api/columns
但是您的服务器将以403 Forbidden
响应,因为GET缺少必需的session_id查询字符串参数。
如果您没有对用户进行身份验证,那么您的数据可能不敏感,任何人都可以调用URI。 CSRF应该是一个非问题,因为没有身份验证,即使您阻止CSRF攻击,攻击者也可以调用您的API服务器端获取您的数据并以他/她想要的方式使用它。
答案 1 :(得分:2)
我会选择'd',因为它清楚地将资源的“信封”与其内容区分开来。这也使消费者更容易解析您的回复,而不是“猜测”给定资源的包装属性的名称,然后才能访问它所拥有的内容。
我认为你在谈论两件不同的事情:
application/x-www-form-urlencoded
中发送。如果您选择在回复中包含新创建的资源的表示,则您的响应应该基本上镜像GET。 (在HTTP中不是强制性的。)答案 2 :(得分:1)
使用'Columns',因为它在语义上有意义。它有助于思考JSON和XML如何相互映射。
如果您要将该集合丢回,您可以使用相同的媒体类型(语法,格式,您将其称之为。)