从 rest API 获取页面结果:最佳实践

Getting pages results from rest API: Best practice

对休息还很陌生API,到目前为止只做了一些相当基本的查询来获得我需要的东西。

正在编写一个新的 PowerShell 脚本,使用 rest 提取所有设备:

$url = "https://my-site.com/internal/api"

然后查询所有设备并将这些结果分配给一个变量,这样我就可以稍后在整个脚本的不同点上使用该变量进行操作:

$devices = Invoke-RestMethod -uri "$url/devices" -UseDefaultCredentials -Method Get -ContentType "application/json"

一万多个结果,我想做的是能够在所有返回的页面中搜索结果。

到目前为止我已经知道我可以做这样的事情来在一页中获得所有结果:

$devicespagetest = Invoke-RestMethod -uri "$url/devices?pagesize=99999" -UseDefaultCredentials -Method Get -ContentType "application/json"

这是不好的做法吗?

有没有更有效的或程序化的方法来实现这个而不像我上面那样做?

我不确定我们使用的是哪种 Rest API,但我知道我们没有将它与 Jira 或 Confluence 集成。

你说的API是自己开发的吗?

编辑:刚刚看到您在标签中调用了 WordPress API。 WordPress offers pagination links,并通过自定义 headers.

提供有用的分页信息

通常,REST APIs 在通过查询参数(例如:“offset”和“max”)返回资源列表时提供分页支持。 offset 参数指示应跳过多少结果,而 max(或您的情况下的页面大小)确定您要获取的最大结果。

例如http://myapi.com/persons?_offset=0&_max=20 represents the first 20 persons in your list. In the context of the HATEOAS constraint, it is recommended to provide HTTP Link response headers so that clients know how to navigate through the pages using the “previous”, “first”, “next”, and “last” relationships (standardized in RFC 5988).

例如:

GET /persons?_offset=30&_max=10 HTTP/1.1
Host: myapi.com
Accept: application/json

结果如下:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 934
Link: <http://myapi.com/persons?_offset=0&_max=10>; rel="first"
Link: <http://myapi.com/persons?_offset=20&_max=10>; rel="previous"
Link: <http://myapi.com/persons?_offset=40&_max=10>; rel="next"
{body}

为了保护请求整个列表资源的客户端的服务器(即不指定分页参数),建议使用以下方法。当客户端请求列表资源时(例如 http://myapi.com/persons),服务器会将客户端重定向到前 X(例如 10)个项目。

对应的HTTP会话如下所示:

GET /persons HTTP/1.1
Host: myapi.com
Accept: application/json

结果如下:

HTTP/1.1 303 See Other
Location: http://myapi.com/persons?_offset=0&_max=10

接下来,客户端遵循重定向:

GET /persons?_offset=0&_max=10 HTTP/1.1
Host: myapi.com
Accept: application/json

这导致以下响应:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 850
Link: <http://myapi.com/persons?_offset=40&_max=10>; rel="next"
Link: <http://myapi.com/persons?_offset=120&_max=10>; rel="last"
{body}

请注意,在需要 CORS (Cross Origin Resource Sharing) 的环境中,重定向可能会导致问题。在这种情况下,GET /persons 检索到的部分列表的表示可以简单地指示检索到的人数以及总共有多少人(可选)。

如果您的 API 提供了这样的导航链接,最好使用它们并使用 Invoke-RESTMethod 实现循环并为您的搜索动态构建索引,而不是一次获取 10000 个结果,这会给您的服务器带来不必要的压力。但是在不了解您的用例的情况下,很难给您适当的建议。

谢谢大卫

根据获得的 previousurl 和 nexturl 值,我将以下内容放在一起:

$Devurl = "https://my-site.com/internal/api"
$restResults = Invoke-RestMethod -uri "$Devurl/$device" -UseDefaultCredentials -Method Get -ContentType "application/json"

$resultpages = $restResults.Pages
$incpages = ''
$testarray = @()

Do {
    [int]$incpages += 1
    $url = ($restResults.nexturl) -replace 'page=1',"page=$incpages"
    $url
    $getresults = Invoke-RestMethod -uri $url -UseDefaultCredentials -Method Get -ContentType "application/json"
    $testarray += $getresults.Models
    $resultpages -= 1
    } while ($resultpages -gt 0)

如果我再过滤结果:

$testarray | where {$_.os -like '*windows*'} | select hostname,os

我看到了我所期望的。

这就是您所说的那种循环吗?