Страницы: 1
RSS
PQ, Как организовать функцию с рекурсивным запросом по API?, как забирать данные, если ресурс отдает информацию частями, с указанием параметра для следующего запроса
 
Добрый день!

Есть ресурс, который при запросе с параметром dateFrom возвращает список номеров из системы с указанной даты по текущий момент. Но проблема в том что делает он это частями, и каждая часть содержит информацию для следующей части запроса.

Выглядит это так:
Делаем первый запрос, нам возвращается ответ в таком формате
Код
 "totalHits": 23680,
    "searchAfter": 161978,
    "ids": [
        167057,
        167056,
        167055,
        167054,
Чтобы сделать второй запрос на следующую порцию номеров надо к этому же запросу добавить searchAfter=161978, который содержался в ответе на первый запрос

На итог, требуется получать куски списка до тех пор, пока ответ ресурса не станет пустым
Код
[]
и склеить полученные куски в один список.

Линк на ресурс:
"https://0pryln0q2f.execute-api.eu-central-1.amazonaws.com/API/search?searchAfter=&dateFrom=2..."
Интуиция подсказывает что нужно сделать функцию, которая будет получать дату и рекурсивно выполняться для получения всех кусков и отдавать склеенный лист.

Самому не получается сделать, опыта и знаний не хватает, я либо получаю циклическую ссылку, либо только первый кусок.
Помогите, пожалуйста!

начал с этого и дальше застрял
Код
(x)=>
let
    startdate = (Date.ToText(x, "yyyy-MM-dd")), 
    
    idlist  = Json.Document(Web.Contents(
      "https://0pryln0q2f.execute-api.eu-central-1.amazonaws.com/API/search?searchAfter=&dateFrom=" & startdate,
      [
        Query=[dateFrom=startdate]] 
      )),
    searchAfter = idlist[searchAfter]
    
in
    searchAfter
 
Может кто то сможет заставить эту схему работать?
Код
(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= оставил пустым, чтоб не упиралось в верхний лимит и не приходилось руками лазить поправлять границу.

Благодарю!
 
На List.Generate - симпатичнее выходит ;)
Код
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,  :)  точно говорят, чем код короче и проще - тем лучше)

в скорости разницы не заметил, а вот внедрять проще будет второй вариант)

Спасибо еще раз)
 
Андрей 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

оставлю тут решение для следующих поколений искателей ;)

Страницы: 1
Наверх