获取 RESTful 请求看到的返回计数
Posted
技术标签:
【中文标题】获取 RESTful 请求看到的返回计数【英文标题】:Getting a count of returns seen by a RESTful request 【发布时间】:2009-10-23 00:49:01 【问题描述】:所以,我想知道我将从 RESTful uri GET 请求中获得多少结果。在这一点上,我不知道有什么方法可以做到这一点。有没有办法做到这一点?由于 REST 只是抛出属性,我不知道它是否能够计算其结果,但它可以跳过结果并获取结果的子集。
有人有什么建议吗?
哦,我的设置是填充可查询通用列表的 LINQ to SQL。数据服务使该列表可用。我已经尝试在列表中计数,但我总是得到数据库的最大行数,这不是我想要的。
【问题讨论】:
我不知道你所说的“REST 只是抛出属性”是什么意思。 对不起,我的意思是它只是暴露数据。它不像 SOAP,您可以通过调用函数来获得结果。诚然,您可以在公开数据之前对数据进行操作并进行一定程度的更改,但这基本上就是我的意思。 【参考方案1】:其他人可能会反对这个概念,但是,这对我来说似乎是合理的:
HEAD /your/api HTTP/1.1
HTTP/1.1 200 OK
Date: Fri, 23 Oct 2009 00:58:17 GMT
Content-Type: application/xml; charset=UTF-8
Content-Length: 89
X-Result-Count: 100000000
然后:
GET /your/api HTTP/1.1
HTTP/1.1 200 OK
Date: Fri, 23 Oct 2009 00:58:17 GMT
Content-Type: application/xml; charset=UTF-8
Content-Length: 89
X-Result-Count: 100000000
<?xml version="1.0" encoding="UTF-8"?>
<results>
100000000 results go here.
</results>
注意:这里使用 HEAD 请求来获取计数,而无需拉取完整的数据集。 HEAD 请求仅检索 HTTP 标头,而不是响应的正文。
这将是我能想到的最 RESTful 的方式来指示您在通过网络发送之前将获得多少结果。主要技巧只是想出最好的标题名称。 X-Result-Count
不错,但如果你能找到现有技术并重用他们的标题名称选择,那就更好了(只要他们没有把它命名为非常愚蠢的东西)。话虽如此,我预计你不会有太多运气,所以你应该坚持使用X-Result-Count
。
另外,我认为您可能误解了“REST”的实际含义。没有理由不能按范围给出表示。例如:
GET /your/api?page=1&perpage=10 HTTP/1.1
HTTP/1.1 200 OK
Date: Fri, 23 Oct 2009 00:58:17 GMT
Content-Type: application/xml; charset=UTF-8
Content-Length: 101
X-Result-Count: 10
<?xml version="1.0" encoding="UTF-8"?>
<results>
First 10 results of 100000000 go here.
</results>
但是,要成为 RESTful,您需要能够告诉客户端 /your/api?range=0-9
或 /your/api?page=1&perpage=10
标识的表示,而不使用带外信息。例如,如果您的/your/api
页面会返回太多结果,请临时重定向到/your/api?page=1&perpage=10
,并包含指向/your/api?page=2&perpage=10
的超链接。请注意,此上下文中的超链接可能很简单,例如:
<?xml version="1.0" encoding="UTF-8"?>
<results>
<result>
This is a result.
</result>
<result>
This is also a result.
</result>
<link rel="next" href="/your/api?page=3&perpage=2" />
<link rel="prev" href="/your/api?page=1&perpage=2" />
</results>
现在导航 API 调用结果的信息是带内的,实际上是 RESTful。
从本质上讲,REST 是普通的老式 HTTP,缓存做得正确,并且通常是合理的 URIs 投入了很好的衡量。它也是“作为应用程序状态引擎的超文本”(即资源应该链接到其他资源)。它不是一种协议,而是一种架构风格。任何告诉你不同的人最好叫 Roy Fielding。
http://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven#comment-718附录:
如果您想指示总计数与页数,您可以像这样定义标题:
X-Result-Count: 0-9/100000000
或根据需要进行调整。
【讨论】:
嗯,看起来您的计数被归入该计数附带的全部结果中,对吗?所以我的意思是,如果我只从全套中选择前 10 个,计数会说 10,我会得到 10 个项目。我想要的是一种获取所有项目请求计数的方法,即使我想使用(page=、top=、next= 等)获取一小部分完整数据。我想要得到计数,这样我就可以获得信息将适合的表格所需的行大小的准确数字。有什么想法吗? 另外,我真的不想抓取所有数据只是为了计算有多少。那会破坏我为什么需要计数的目的。 @georryan 对,这就是为什么它是一个 HEAD 请求。 HEAD 请求意味着您仅获取标头,在这种情况下将包括计数,但不包括数据。此外,因为您正在定义标头,所以您可以返回任何您想要的数据。 我正在使用 ADO.Net 数据服务来创建我的 REST 端点。事实证明,有一个新版本的框架为我提供了我需要的确切信息。我可以通过使用“$inlinecount=allpages”或“$count”来获得我正在寻找的计数。我不得不下载新版本,但它给了我所需要的东西。您的所有建议肯定让我朝着帮助我找到答案的方向前进。谢谢! mstecharchitect.blogspot.com/2009/09/…mstecharchitect.blogspot.com/2009/09/… 有趣。您能否将您对此问题的完整解决方案添加为答案?在我看来,它返回了一个数据提要,其中嵌入了 XML 中的总计数,所以你仍然得到第一页吗?【参考方案2】:您为什么不让您的资源处理针对该类型元数据的查询?假设
GET /items
返回您的项目列表,如下所示:
<items count="5" modified="2009-10-22">
<item url="/items/first" name="First Item" />
<item url="/items/second" name="Second Item" />
...
</items>
然后是这样的:
GET /items?info
可以像这样返回一个空列表:
<items count="5" modified="2009-10-22" type="info" />
或者可能是这样的通用信息文档:
<info>
<items count="5" modified="2009-10-22" url="/items" />
</info>
你也可以像这样实现一个“信息”资源:
GET /info?items&users
可能会返回:
<info>
<items count="5" modified="2009-10-22" url="/items" />
<users count="8" modified="2009-10-05" url="/users" />
</info>
【讨论】:
-1 这个概念没有正确考虑 HTTP 缓存。将两种资源组合成一个 HTTP 请求/响应可以减少缓存命中的机会。它还阻止客户端有效地使用If-Modified-Since
和Last-Modified
。此外,Last-Modified
是将该信息返回给客户端的适当方式,使用 HEAD 请求执行此操作是完全合理的。如果您正在打开单个 HTTP 会话并且资源是数千(或更多)字节而不是数百字节,那么批处理的优势就很小,因为会话本身就是一个批处理。
我不太确定你在这里说什么——你是说使用“GET /items”和“GET /items?info”会破坏缓存吗?如果是这样,那么代替“?info”查询,“GET /items/info”会更有意义吗?
不,我是说在同一响应中返回有关项目和用户的信息是不好的。将它们放在单独的请求和响应中。
@Bob Aman - 除了集合中的项目数量不是元数据,它是集合资源本身的真正数据成员。并且将部分资源数据作为 HTTP 标头传递绝对不是一个好主意。
@Franci 哇,真的吗?因为它不是***定义的类别之一,所以它不是元数据?来自同一篇 Wikipedia 文章:“元数据被松散地定义为关于数据的数据。”计数是关于集合中有多少数据项的数据。因此,元数据。无论如何,这是一个非常愚蠢的论点。【参考方案3】:
为什么不让 REST Web 服务仅以 JSON 或 XML 的形式返回数据,在那里你可以有一个关于长度的属性。
【讨论】:
我不想一次得到所有结果。我正在尝试分批填充表格,但我想知道完整结果集的总数。 当您发出初始请求时,您会取回第一批和一个总数,或者一个仍然剩余的数字。然后您只需循环并获取下一批,直到您获得所有信息。但是,要么服务器端是有状态的,要么您每次都对数据库进行额外查询以获取有限数量的结果。如果您将其返回排序后会发生什么,并且您在 G 上,但是以 C 开头的内容被插入到数据库中,您将无法显示新的更改。或者,只需按 ID 排序。 您是说 xml 或 json 响应中已经嵌入了一个长度?哪里是?它在标题中吗?我实际上是在使用 .net 来创建我的 RESTful 输出,但我看不到 xml 输出有任何计数。 你会传回一个属性('numberremaining'),这样每次你传回数据时,这个数字应该会减少,但你只需将它放入,然后放入你想要的数据回传。您应该能够在您的 REST 资源名称设计中考虑到这一点。您可以从以下内容开始:
/widget/12345(小部件12345的表示) /widgets(所有widget资源名称的列表,即链接)您可能很快决定“/widgets”将是一个巨大的列表并决定支持页面,例如
/widgets/page/43(这可能包含指向第 4200 到第 4299 个小部件的链接,以及页面总数或小部件计数等附加信息。)在其他情况下,您可以将一个大集合细分为自然层次结构:
/widgets/mahogany, /widgets/oak, ... /电影/戏剧,/电影/浪漫,... /computers/harddrives/seagate, /computers/usbdrives/kingston您也可以定义查询:
/widgets?maxprice=200&maxweight=4【讨论】:
以上是关于获取 RESTful 请求看到的返回计数的主要内容,如果未能解决你的问题,请参考以下文章
如何将 iOS 应用程序连接到 Symfony2 RESTful Webservice?