获取 RESTful 请求看到的返回计数

Posted

技术标签:

【中文标题】获取 RESTful 请求看到的返回计数【英文标题】:Getting a count of returns seen by a RESTful request 【发布时间】:2010-12-09 07:30:04 【问题描述】:

所以,我想知道我将从 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&amp;perpage=10 标识的表示,而不使用带外信息。例如,如果您的/your/api 页面会返回太多结果,请临时重定向到/your/api?page=1&amp;perpage=10,并包含指向/your/api?page=2&amp;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-SinceLast-Modified。此外,Last-Modified 是将该信息返回给客户端的适当方式,使用 HEAD 请求执行此操作是完全合理的。如果您正在打开单个 HTTP 会话并且资源是数千(或更多)字节而不是数百字节,那么批处理的优势就很小,因为会话本身就是一个批处理。 我不太确定你在这里说什么——你是说使用“GET /items”和“GET /items?info”会破坏缓存吗?如果是这样,那么代替“?info”查询,“GET /items/info”会更有意义吗? 不,我是说在同一响应中返回有关项目和用户的信息是不好的。将它们放在单独的请求和响应中。 @Bob Aman - 除了集合中的项目数量不是元数据,它是集合资源本身的真正数据成员。并且将部分资源数据作为 HTTP 标头传递绝对不是一个好主意。 @Franci 哇,真的吗?因为它不是***定义的类别之一,所以它不是元数据?来自同一篇 Wikipedia 文章:“元数据被松散地定义为关于数据的数据。”计数是关于集合中有多少数据项的数据。因此,元数据。无论如何,这是一个非常愚蠢的论点。【参考方案3】:

您应该能够在您的 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

【讨论】:

【参考方案4】:

为什么不让 REST Web 服务只以 JSON 或 XML 的形式返回数据,在那里你可以有一个关于长度的属性。

【讨论】:

我不想一次得到所有结果。我正在尝试分批填充表格,但我想知道完整结果集的总数。 当您发出初始请求时,您会取回第一批和一个总数,或者一个仍然剩余的数字。然后您只需循环并获取下一批,直到您获得所有信息。但是,要么服务器端是有状态的,要么您每次都对数据库进行额外的查询以获得有限数量的结果。如果您将其返回排序后会发生什么,并且您在 G 上,但是以 C 开头的内容被插入到数据库中,您将无法显示新的更改。或者,只需按 ID 排序。 您是说 xml 或 json 响应中已经嵌入了一个长度?哪里是?它在标题中吗?我实际上是在使用 .net 创建我的 RESTful 输出,但我看不到 xml 输出有任何计数。 你会传回一个属性('numberremaining'),这样每次你传回数据时,这个数字应该会减少,但你只需输入它,然后输入你想要的数据回传。 500...

以上是关于获取 RESTful 请求看到的返回计数的主要内容,如果未能解决你的问题,请参考以下文章

RESTFUL如何指导WEB API设计?

如何将 iOS 应用程序连接到 Symfony2 RESTful Webservice?

RESTful

在Struts2 RESTful插件POST请求中返回响应

以 RESTful 方式递增资源计数器:PUT 与 POST

RESTful的详解