PQ, Как организовать функцию с рекурсивным запросом по API?, как забирать данные, если ресурс отдает информацию частями, с указанием параметра для следующего запроса
Есть ресурс, который при запросе с параметром dateFrom возвращает список номеров из системы с указанной даты по текущий момент. Но проблема в том что делает он это частями, и каждая часть содержит информацию для следующей части запроса.
Выглядит это так: Делаем первый запрос, нам возвращается ответ в таком формате
Чтобы сделать второй запрос на следующую порцию номеров надо к этому же запросу добавить searchAfter=161978, который содержался в ответе на первый запрос
На итог, требуется получать куски списка до тех пор, пока ответ ресурса не станет пустым
(optional startDate as text, optional continuationToken as text, optional loop as number, optional data as list) =>
let
Source =if continuationToken = null
then Json.Document(Web.Contents("https://0pryln0q2f.execute-api.eu-central-1.amazonaws.com/API/search?dateFrom=" & startDate & ""))
else Json.Document(Web.Contents("https://0pryln0q2f.execute-api.eu-central-1.amazonaws.com/API/search?searchAfter=" & continuationToken & "&dateFrom=" & startDate & ""))
,
token = Text.From(Source[searchAfter]),
currentData = Source[ids],
appendedData =
if currentData is null and data is null then {}
else if data is null then List.Combine({{}, currentData})
else if data is null then List.Combine({data,{}})
else List.Combine({data, currentData}),
loopNum = loop + 1,
output =
if Source is null or loopNum > 100
then
if appendedData is null then {1,2,3} else appendedData
else @#"GET"(startDate, token, loopNum, appendedData)
in
appendedData
Уж вроде все предусмотрел, все равно не выходит. Не могу понять в чем причина((
Доброе время суток. Попробуйте так поковырять. Что-то List.Generate у меня не взлетел. Лень разбирать, хотя из результата List.Accumulate понятно в чём проблема.
Код
let
baseQuery = "https://0pryln0q2f.execute-api.eu-central-1.amazonaws.com/API/search?searchAfter=",
tryItems = {1..100},
response = List.Accumulate(tryItems, {Json.Document(Web.Contents("https://0pryln0q2f.execute-api.eu-central-1.amazonaws.com/API/search?searchAfter=161996"))}, (acc, next) =>
let
last = List.Last(acc),
new = if last is record then Json.Document(Web.Contents(baseQuery & Text.From(last[searchAfter]))) else null
in
acc & {new}
),
needed = List.Select(response, each _ is record),
toItems = List.Transform(needed, each _[ids]),
result = List.Combine(toItems)
in
result
Андрей VG, спасибо! погонял - все работает. Единственное в List.Accumulate в ссылке searchAfter= оставил пустым, чтоб не упиралось в верхний лимит и не приходилось руками лазить поправлять границу.
let
baseQuery = "https://0pryln0q2f.execute-api.eu-central-1.amazonaws.com/API/search?searchAfter=",
generate = List.Generate(
() => [response = Json.Document(Web.Contents(baseQuery))],
each [response] is record,
each [response = Json.Document(Web.Contents(baseQuery & Text.From([response][searchAfter])))],
each [response][ids]
),
result = List.Combine(generate)
in
result
Андрей VG, тут вдруг выяснилось, что PowerBI считает оба ваших запроса - динамическими, и напрочь отказывается обновляться по расписанию.
К счастью удалось найти лазейку через RelativePath
вот такой апгрейд получился))
Код
let
baseQuery = "https://0pryln0q2f.execute-api.eu-central-1.amazonaws.com/API/search?searchAfter=",
generate = List.Generate(
() => [response = Json.Document(Web.Contents(baseQuery))],
each [response] is record,
each [response = Json.Document(Web.Contents(baseQuery ,
[
RelativePath="",
Query=[searchAfter=Text.From([response][searchAfter])]
]
))],
each [response][ids]
),
result = List.Combine(generate)
in
result
оставлю тут решение для следующих поколений искателей