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

Введение

Создавали ли вы REST API? Или приложения, которые используют некий сторонний REST API? Если вы ответили утвердительно хотя бы на один из этих вопросов, то вы поймёте мою боль. Ранее (очень ранее) для подобных задач я создавал отдельный файл, в котором сохранял JavaScript-сниппеты, которые выполняли REST-запросы к тестируемым API. Моим обычным пайплайном при обращении к среднестатистическому API был следующий:

  1. Копируем нужный запрос из файла
  2. Выполняем запрос на получение token-а
  3. Копируем следующий запрос из файла
  4. Копируем token в новый запрос
  5. Выполняем запрос на получение данных

Пункты 3-5 могут продолжаться еще несколько раз. Если это одноразовая задача, то проблем нет - выполнил и забыл. Однако, если вы используете этот API в своём приложении или сами являетесь разработчиком API, то выполнять эту пачку запросов требуется многократно и делать это становится неприятно. В этот момент появляется ОН - Postman. Создатели Postman так описывают свой проект:

Postman is the swiss army knife of API tools, allowing you to design, build, test, document and monitor your services, all in one place.*

Если вкратце и по-русски, то Postman - это комбайн, который позволяет создавать и выполнять запросы, документировать и мониторить ваши сервисы в одном месте.

Установка

Postman доступен как Chrome App, который можно установить из магазина приложений Chrome, и [standalone приложения для MacOS](https://www.getpostman.com/app/postman- osx?utm_source=site&utm_medium=homepage&utm_campaign=macapp). Версии для Linux пока нет, но авторы обещают в скором времени это исправить. Postman доступен как standalone-приложение для Windows, MacOS и Linux. На момент написания данной статьи так же существовала версия для Google Chrome о которой пойдёт речь в этой статье.

Выполнение запросов

Базовая функциональность довольная проста: для выполнения элементарных запросов достаточно:

  1. выбрать тип запроса
  2. вбить запрос в соответствующее поле …
  3. … или заполнить параметры через форму
  4. нажать кнопку “Send”

2016-09-18_20-13-06.png Если все сделано правильно, то в нижней части окна отобразится результат выполненного запроса. В моём случае - запрос к знакомому по предыдущим постам API StackOverflow:

https://api.stackexchange.com/2.2/search?page=1&pagesize=15&fromdate=1474156800&todate=1474243200&order=desc&sort=activity&tagged=c%23&site=stackoverflow

“Этот пример примитивен и выполнить это проще в %Developer-Tools-Fav- Browser%!” - скажет любой, и я с этим соглашусь. Однако есть как минимум одно “но”: этот запрос можно сохранить и выполнять в будущем только изменяя соответствующие параметры. Более того, запросы можно группировать в коллекции.

Коллекции запросов

Сайт thetvdb.com предлагает возможность получать информацию по различным сериалам посредством их REST API. Однако, каждый запрос должен содержать в заголовках полученный при аутентификации токен. Таким образом для того, чтобы получить информацию по сериалу “Walking Dead” необходимо выполнить два запроса: получение токена и поиск. Создадим новый POST-запрос на адрес

https://api.thetvdb.com/login

для получения токена: 2016-09-18_14-11-15 Заполним форму с заголовками как указано на изображении выше и добавим в тело запроса нужный JSON и изменим тип на raw (apikey, username и userkey можно получить в личном кабинете после регистрации на вышесказанном сайте): 2016-09-18_14-12-23 На данный момент этого достаточно и можно опять жать на “Send”. В ответ на этот запрос нам придёт JSON вида

{
 "token": "ваш-токен-для-дальнейших-запросов-в-виде-очень-длинной-строки"
}

Первую часть сделали. Теперь, для того чтобы найти сериал “Walking Dead”, нам необходимо выполнить GET-запрос на следующий адрес:

https://api.thetvdb.com/search/series?name=Walking Dead

Создаем новый запрос, заполняем адрес и добавляем новый заголовок Authorization в соответствующем разделе (1): 2016-09-18_14-23-48 В ответе можно увидеть JSON с полученными сериалами: “The Walking Dead” и “Fear the Walking Dead” и их краткими описаниями (2). Чтобы в дальнейшем можно было просто найти эти запросы - сохраним их через меню “Save As…” и добавим в коллекцию “thetvdb”: 2016-09-18_20-23-39.png Теперь в панели слева у нас будет новая коллекция “thetvdb”.

Выполнение коллекций запросов и тестов

Предыдущий раздел показал, что можно упростить выполнение рутинных действий сохранив запросы и выполнять их с заготовленными параметрами. Однако, после 2-3 однообразных циклов:

  1. Получи токен
  2. Скопируй токен в заголовок запроса
  3. Выполни запрос к API

Это начинает надоедать. И тут на помощь приходит сумасшедшая возможность Postman - выполнение коллекций запросов с добавлением некоторых небольших (а можно и больших) скриптов. Улучшим предыдущие запросы таким образом, чтобы при выполнении запроса на получение токена ничего в последующие вопросы копировать не потребовалось. Для этого есть связка из вкладки Tests, окружений (Environment) и переменных этого окружения. Во-первых, необходимо создать новое окружение в соответствующем разделе: 2016-09-18_15-15-05.png 2016-09-18_15-16-38 2016-09-18_15-19-42 Никакие ключи добавлять не будем - сейчас нам это не надо. Созданное окружение необходимо выбрать в соответствующем выпадающем списке: 2016-09-18_15-24-54.png Во-вторых, откроем запрос на получение токена и перейдём на вкладку Tests (см. скриншот выше) и добавим следующий код:

var jsonData = JSON.parse(responseBody);
postman.setEnvironmentVariable("token", jsonData.token);

Этот скрипт только лишь преобразует строку в JSON и сохраняет в переменную текущего окружения “token” свойство token полученного объекта. На самом деле эта вкладка предназначена немного для других целей (для написания тестов, внезапно), но сейчас об этом говорить не будем. Возможно, в следующий раз доберусь и до этого. В-третьих, изменим запрос на получение списка сериалов “Walking Dead” таким образом, чтобы токен получался из переменных окружения. Для этого достаточно в заголовке Authorization строку токена заменить на сниппет {{token}}: 2016-09-18_15-27-49.png Теперь после выполнения запроса для получения токена можно сразу же выполнять запрос на поиск сериала без лишних манипуляций с копированием полученного токена. Можно проверить, что всё работает корректно выполнив всю коллекцию запросов через соответствующее меню коллекции: 2016-09-18_15-40-02.png В открывшемся меню выбираем нужную коллекцию и жмём большую синюю кнопку “Start Test”, которая выполнит все запросы выбранной коллекции в той последовательности, в которой они сохранены: 2016-09-18_15-42-32.png Как можно видеть на скриншоте все запросы завершились удачно. К сожалению, содержимое ответов этих запросов посмотреть здесь нельзя. Оно и правильно - возможность выполнения коллекции запросов предполагается для тестирования API в первую очередь.

Генерация сниппетов

И, напоследок, хотелось бы упомянуть об одной очень крутой фиче Postman - генерация кода из запроса. Список поддерживаемых языков программирования (и не только) довольно широк: от OCaml и cURL до Swift и Go. Пример кода, сгенерированного Postman для поиска по StackOverflow на Golang:

package main

import (
 "fmt"
 "net/http"
 "io/ioutil"
)

func main() {

 url := "https://api.stackexchange.com/2.2/search?page=1&pagesize=15&fromdate=1474156800&todate=1474243200&order=desc&sort=activity&tagged=c%2523&site=stackoverflow"

 req, _ := http.NewRequest("GET", url, nil)

 req.Header.Add("cache-control", "no-cache")
 req.Header.Add("postman-token", "5db2449c-ce3f-4937-cdd3-799d7499a909")

 res, _ := http.DefaultClient.Do(req)

 defer res.Body.Close()
 body, _ := ioutil.ReadAll(res.Body)

 fmt.Println(res)
 fmt.Println(string(body))

}

На JavaScript:

var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
 if (this.readyState === 4) {
 console.log(this.responseText);
 }
});

xhr.open("GET", "https://api.stackexchange.com/2.2/search?page=1&pagesize=15&fromdate=1474156800&todate=1474243200&order=desc&sort=activity&tagged=c%2523&site=stackoverflow");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.setRequestHeader("postman-token", "bdcd4f52-1cd3-0304-c300-cb947bc119bb");

xhr.send(data);

И в добавок на Python с использованием библиотеки Requests:

import requests

url = "https://api.stackexchange.com/2.2/search"

querystring = {"page":"1","pagesize":"15","fromdate":"1474156800","todate":"1474243200","order":"desc","sort":"activity","tagged":"c%23","site":"stackoverflow"}

headers = {
 'cache-control': "no-cache",
 'postman-token': "ea8fdb1f-dc8a-6e31-63cf-fbb85366f6ca"
 }

response = requests.request("GET", url, headers=headers, params=querystring)

print(response.text)

Как мне кажется, код выглядит приемлемым более чем и вполне годится как отправная точка для дальнейшего шлифования.

Выводы

Вывод только один - если вы еще не используете в повседневной работе Postman, то, вероятно, скоро начнёте. Если нет, то, видимо, оно вам не надо и вы хотите еще больше страданий. *) Postman - это швейцарский нож для работы с API, который позволяет создавать, тестировать, документировать и мониторить ваши сервисы из одного места.

UPD: Более подробно работу с переменными и окружениями разобрал в отдельной статье.

UPD 2: Запись вебинара, в которой я рассказываю приблизительно тоже самое: