Как я могу визуализировать мэшап API в Postman?

У меня есть REST API классических актеров, которые я хочу визуализировать в Postman. URL-адреса изображения актера нет в API, поэтому мне нужно будет создать мэшап из комбинации основного API и другого API.

1. Предпосылки

Основной API / конечная точка находится по адресу http://henke.atwebpages.com/postman/promises/actors.json:

      {
  "area": {
    "name": "United States",
    "type": null
  },
  "release-groups": [
    {
      "primary-type": "Actor",
      "fullname": "Katharine Hepburn",
      "id": "Q56016",
      "born": "1907"
    },
    {
      "primary-type": "Actor",
      "fullname": "Humphrey Bogart",
      "id": "Q16390",
      "born": "1899"
    }
  ],
  "country": "US",
  "name": "Classical Actors",
  "life-span": {
    "begin": "1899",
    "ended": true,
    "end": "2003"
  }
}

URL-адреса изображений Кэтрин Хепберн и Хамфри Богарт находятся по адресу:
http://henke.atwebpages.com/postman/promises/coverart/Q56016.json и
http://henke.atwebpages.com/postman/promises/coverart/Q16390.json соответственно.

Соответствующий JSONS, Кэтрин Хепберн:

      {
  "images": [
    {
      "front": true,
      "thumbnails": {
        "small": "https://upload.wiki [...] 220px-Tom_cruise_1989.jpg",
        "large": "https://upload.wiki [...] -TomCruiseDec08MTV_cropped.jpg"
      },
      "back": false,
      "edit": 18084161
    },
    {
      "back": true,
      "edit": 39938947,
      "front": false,
      "thumbnails": {
        "small": "https://upload.wiki [...] -Katharine_Hepburn_promo_pic.jpg",
        "large": "https://upload.wiki [...] Tom_Cruise_by_Gage_Skidmore_2.jpg"
      }
    }
  ]
}

и Хамфри Богарт:

      {
  "images": [
    {
      "edit": 40403385,
      "back": true,
      "thumbnails": {
        "small": "https://upload.wiki [...] 220px-Humphrey_Bogart_1940.jpg",
        "large": "https://upload.wiki [...] px-TomCruiseByIanMorris2010.jpg"
      },
      "front": false
    },
    {
      "edit": 40403384,
      "back": false,
      "thumbnails": {
        "small": "https://upload.wiki [...] 220px-Tom_cruise_1989.jpg",
        "large": "https://upload.wiki [...] -TomCruiseDec08MTV_cropped.jpg"
      },
      "front": true
    }
  ]
}

где я усек ссылки на изображения для лучшей читаемости.

Обратите внимание в основном API, как каждый объект / человек имеет уникальный id ( Q56016 для Кэтрин Хепберн и Q16390 для Хамфри Богарта) и fullname. Остальные конечные точки имеют - для каждого объекта в release-groupsмассив основного API - тот же уникальный идентификатор вместе со ссылкой на изображение / портрет. Таким образом, информация со всех трех конечных точек необходима для составления списка каждого актера с совпадающим изображением.

2. Желаемый результат

Очевидно, проблема решена, если данные в API-интерфейсах можно объединить вместе таким образом, чтобы для каждого идентификатора предоставлялось как имя, так и ссылка на изображение:

      [
  {
    "name": "Katharine Hepburn",
    "image": "https://upload.wiki [...] -Katharine_Hepburn_promo_pic.jpg"
  },
  {
    "name": "Humphrey Bogart",
    "image": "https://upload.wiki [...] 220px-Humphrey_Bogart_1940.jpg"
  }
]

Затем осталось визуализировать данные в Postman.

3. Методология

Я напишу весь код в одном скрипте Tests запроса Postman. Этот запрос - всего лишь пустышка , не имеющая никакой другой цели, кроме запуска кода JavaScript в сценарии тестов .

Чтобы создать мэшап и затем отобразить результат, было бы удобно использовать хорошо известный а затем получать изображения с помощью Promise.all.

Одно предостережение заключается в том, что Postman не реализует Fetch API,Fetch API .
Но, к счастью, есть ответ , объясняющий, как имитировать команду в Postman.
Это можно сделать следующим образом:

      function fetch (url) {
  return new Promise((resolve, reject) => {
    pm.sendRequest(url, function (_, fetchResponse) {
      resolve(fetchResponse);
    });
  });
} // ^^ No Fetch API in Postman! But see https://stackoverflow.com/a/67588692

Поскольку эта функция возвращает обещание, она (надеюсь) должна работать так же, как fetch() в любом современном веб-браузере.

Остальная часть раздела Тесты должна построить результат. Обратите внимание, как Promise.all должен быть связан / вложен в исходный запрос fetch(urlOuter)- потому что он не может работать без получения данных из первого запроса. Это аналогично второму фрагменту стека .
Наконец, результат должен быть визуализирован:1

      const lock = setTimeout(() => {}, 43210);
const fullnames = [];
const urls = [];
const urlOuter = 'http://henke.atwebpages.com/postman/promises/actors.json';
fetch(urlOuter).then(responseO => responseO.json()).then(responseBodyO => {
  const tblHeader = responseBodyO.name;
  const actors = responseBodyO['release-groups'];
  for (const item of actors) {
    fullnames.push(item.fullname);
    urls.push('http://henke.atwebpages.com/postman/promises/coverart/' +
        item.id + '.json');
  }
  return Promise.all(urls.map(url => fetch(url)
    .then(responseI => responseI.json())
    .then(responseBodyI => responseBodyI.images.find(obj =>
      obj.back === true).thumbnails.small)))
    .then(imageURLs => {
      clearTimeout(lock); // Unlock the timeout.
      const actorNames = fullnames.map(value => ({ name: value }));
      const actorImages = imageURLs.map(value => ({ image: value }));
      const actorsAndImages = actorNames.map(
        (item, i) => Object.assign({}, item, actorImages[i]));
      console.log('actorsAndImages:\n' + JSON.stringify(actorsAndImages));
      const template = `<table>
        <tr><th>` + tblHeader + `</th></tr>
        {{#each responseI}}
        <tr><td>{{name}}<br><img src="{{image}}"></td></tr>
        {{/each}}
      </table>`;
      pm.visualizer.set(template, { responseI: actorsAndImages });
    });
}).catch(_ => {
  console.error('Failed to fetch - ' + urlOuter);
});

В почтальоне:

Скрипт Mashup Tests в Postman

4. Работает?

Так это работает? - Ответ и да, и нет.

  • С хорошей стороны, я мог создать желаемый результат JSON, как в разделе 2 выше.
  • С другой стороны, визуализация не работает:

Результат Promise.all в Postman

Сообщение Настроить визуализатор для этого запроса типично, когда pm.visualizer.set()команда была забыта. Но я этого не забыл. Так что же не так?

5. Как повторить мою попытку в Postman

Воспроизвести мою попытку в Postman должно быть несложно.
Предполагая, что вы используете настольную версию Postman, сделайте следующее:

  1. Загрузите и сохраните
    http://henke.atwebpages.com/postman/promises/Promise.all-Actors.pm_coll.json
    в подходящем месте на жестком диске.

  2. В Postman Ctrl+ O> Загрузить файлы> Promise.all-Actors.pm_coll.json> Импорт .
    Теперь вы должны увидеть среди своих коллекций в Postman.

  3. Коллекции> Promise.all-Actors > DummyRequest> Отправить .

  4. В теле ответа почтальона нажмите « Визуализировать» .

  5. Сделанный! - Если все сработало, как задумано, вы должны увидеть результат, как указано выше.

Рекомендации


1 Не запутайтесь в строках const lock = setTimeout(() => {}, 43210); а также clearTimeout(lock);. - Их единственная цель - служить Обходной путь почтальона для известной ошибки: связанные запросы никогда не выполняютсяобходным путем для известной ошибки .

1 ответ

Сообщение « Настройте визуализатор для этого запроса» является типичным, когда команда была забыта. Но я этого не забыл. Так что же не так?

Как уже упоминалось, проблема в том, что . 1
Что это значит? - Ну видимо это означает, что такая функция как pm.visualizer.set()не может быть вызван из обратного вызова Promise . Он должен вызываться из обратного вызова . Обратите внимание, что при построении функции соответствующее обещание фактически находится за пределами обратного вызова!

1. Достижение желаемого результата и его визуализация

Другими словами, вам нужно заменить все вхождения fetch() в коде с pm.sendRequest(). Вам также необходимо реализовать свою собственную версию Promise.all, поскольку он полагается на обещания, которых нет в собственном скрипте Postman.
К счастью, такая реализация была опубликована в .

Вот результирующий код для раздела Тесты , начиная с инициализаций:2

      const lock = setTimeout(() => {}, 43210);
const fullnames = [];
const urls = [];
const urlOuter = 'http://henke.atwebpages.com/postman/promises/actors.json';

Основная часть с несколько нестандартным форматированием во избежание вертикальной прокрутки:

      pm.sendRequest(urlOuter, (_, responseO) => {
  const tblHeader = responseO.json().name;
  const actors = responseO.json()['release-groups'];
  for (const item of actors) {
    fullnames.push(item.fullname);
    urls.push('http://henke.atwebpages.com/postman/promises/coverart/' +
        item.id + '.json'); }
  const images = [];
  let countDown = urls.length;
  urls.forEach((url, index) => {
    asynchronousCall(url, imageURL => {
      images[index] = imageURL;
      if (--countDown === 0) { // Callback for ALL starts on next line.
        clearTimeout(lock); // Unlock the timeout.
        const actorNames = fullnames.map(value => ({ name: value }));
        const actorImages = images.map(value => ({ image: value }));
        const actorsAndImages = actorNames.map(
          (item, i) => Object.assign({}, item, actorImages[i]));
        console.log('actorsAndImages:\n' + JSON.stringify(actorsAndImages));
        const template = `<table>
          <tr><th>` + tblHeader + `</th></tr>
          {{#each responseI}}
          <tr><td>{{name}}<br><img src="{{image}}"></td></tr>
          {{/each}}
        </table>`;
        pm.visualizer.set(template, { responseI: actorsAndImages });
      }
    });
  });
  function asynchronousCall (url, callback) {
    pm.sendRequest(url, (_, responseI) => {
      callback(responseI.json().images.find(obj => obj.back === true)
        .thumbnails.small); // Individual callback.
    }); } });

В почтальоне:

Скрипт Mashup Tests в Postman

2. Работает?

Да! - Оно работает:

Результат Promise.all в Postman

3. Как воспроизвести мое решение в Postman

Предполагая, что вы используете настольную версию Postman, сделайте следующее:

  1. Загрузите и сохраните
    http://henke.atwebpages.com/postman/promises/Actors.pm_coll.json
    в подходящем месте на жестком диске.

  2. В Postman Ctrl+ O> Загрузить файлы> Actors.pm_coll.json> Импорт .

  3. Коллекции> Actors > DummyRequest> Отправить .

  4. В теле ответа почтальона нажмите « Визуализировать» .

  5. Сделанный! - Теперь вы должны увидеть результат, как указано выше.

Рекомендации


1 Я надеюсь , Почтальон будет поддерживать обещания в версии будущего.
2 Опять же, не запутайтесь в строках const lock = setTimeout(() => {}, 43210); а также clearTimeout(lock);. - Их единственная цель - служить обходным путем для известной ошибки .

Другие вопросы по тегам