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

时间:2017-03-06 03:27:13

标签: powershell wordpress-rest-api

相当新的休息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集成。

2 个答案:

答案 0 :(得分:1)

您所称的API是由您自己开发的吗?

修改:刚看到您在标签中调用了WordPress API。 WordPress offers pagination links,并通过自定义标头提供有用的分页信息。

通常,REST API在通过查询参数返回资源列表时提供分页支持(例如:“offset”和“max”)。 offset参数指示应跳过多少结果,max(或者你的情况下为pagesize)决定了你想要获取的结果的最大值。

例如,http://myapi.com/persons?_offset=0&_max=20代表列表中的前20个人。在HATEOAS约束的上下文中,建议提供HTTP链接响应标头,以便客户端知道如何使用“上一个”,“第一个”,“下一个”和“最后一个”关系在页面中导航(在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 /人员检索的部分列表的表示可以简单地指示检索了多少人以及总共有多少人(可选)。

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

答案 1 :(得分:0)

谢谢大卫

基于获得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

我明白了我的期望。

这是你所说的那种循环吗?