Как я могу визуализировать мэшап 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);
});
В почтальоне:
4. Работает?
Так это работает? - Ответ и да, и нет.
- С хорошей стороны, я мог создать желаемый результат JSON, как в разделе 2 выше.
- С другой стороны, визуализация не работает:
Сообщение Настроить визуализатор для этого запроса типично, когда
pm.visualizer.set()
команда была забыта. Но я этого не забыл. Так что же не так?
5. Как повторить мою попытку в Postman
Воспроизвести мою попытку в Postman должно быть несложно.
Предполагая, что вы используете настольную версию Postman, сделайте следующее:
Загрузите и сохраните
http://henke.atwebpages.com/postman/promises/Promise.all-Actors.pm_coll.json
в подходящем месте на жестком диске.В Postman Ctrl+ O> Загрузить файлы>
Promise.all-Actors.pm_coll.json
> Импорт .
Теперь вы должны увидеть среди своих коллекций в Postman.Коллекции>
Promise.all-Actors
>DummyRequest
> Отправить .В теле ответа почтальона нажмите « Визуализировать» .
Сделанный! - Если все сработало, как задумано, вы должны увидеть результат, как указано выше.
Рекомендации
- Викиданные о Кэтрин Хепберн
- Викиданные о Хамфри Богарте
- этого ответаКак запускать вложенные запросы в JavaScript - 2-й фрагмент
- Как я могу получить массив URL-адресов с помощью Promise.all?
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.
}); } });
В почтальоне:
2. Работает?
Да! - Оно работает:
3. Как воспроизвести мое решение в Postman
Предполагая, что вы используете настольную версию Postman, сделайте следующее:
Загрузите и сохраните
http://henke.atwebpages.com/postman/promises/Actors.pm_coll.json
в подходящем месте на жестком диске.В Postman Ctrl+ O> Загрузить файлы>
Actors.pm_coll.json
> Импорт .Коллекции>
Actors
>DummyRequest
> Отправить .В теле ответа почтальона нажмите « Визуализировать» .
Сделанный! - Теперь вы должны увидеть результат, как указано выше.
Рекомендации
- Postman изначально не поддерживает обещания
pm.sendRequest
возвращает объект pm, а не обещание - ответе позавчераКак получить массив URL-адресов без Promise.all
1 Я надеюсь , Почтальон будет поддерживать обещания в версии будущего.
2 Опять же, не запутайтесь в строках
const lock = setTimeout(() => {}, 43210);
а также
clearTimeout(lock);
. - Их единственная цель - служить обходным путем для известной ошибки .