Все разделы

Основные возможности

Импорт и экспорт

На этой странице

Tetiva читает коллекции Postman v2.1, Insomnia и Hoppscotch, спецификации OpenAPI 3.0 и 3.1 и Swagger 2.0, HAR-файлы и окружения Postman и Hoppscotch, а выгружает в формате Postman v2.1. Коллекцию, опубликованную на share.tetiva.app, приложение скачает по ссылке или откроет из файла .tetiva.json, скачанного со страницы. Отдельный запрос можно забрать из приложения командой cURL или кодом на другом языке. Импорт создаёт коллекцию со всей вложенностью прямо в текущем рабочем пространстве, экспорт отдаёт файл через системный диалог сохранения. cURL работает в обе стороны: команду можно скопировать из приложения и вставить в него.

Импорт коллекции#

Кнопка импорта над деревом коллекций открывает меню из двух пунктов: «Импорт из файла…» и «Импорт по ссылке…». Из файла читаются коллекции Postman v2.1, Insomnia (экспорт v4 в JSON или YAML и файлы v5 в YAML) и Hoppscotch, спецификации OpenAPI и Swagger в JSON или YAML, HAR-файлы и файлы .tetiva.json со страниц опубликованных коллекций. Формат приложение определяет по содержимому, а диалог выбора показывает файлы .json, .yaml, .yml и .har. Файл больше 48 МБ импорт отклонит, не читая, а файл .tetiva.json — уже больше 8 МБ. Экспорт Postman v2.0 будет отклонён с просьбой переэкспортировать коллекцию в v2.1, а файл v1 приложение не узнает и ответит общей ошибкой «Это не коллекция Tetiva, Postman, Insomnia или Hoppscotch…». Тот же пункт «Импорт из файла…» есть в контекстном меню коллекции: импортированное дерево он вложит внутрь выбранной коллекции, а файл Tetiva всегда становится новой коллекцией верхнего уровня. Файл окружения Postman или Hoppscotch, выбранный здесь же, сразу импортируется как окружение, об этом ниже.

Tetiva
v1.3.1
Контекстное меню коллекции в Tetiva с пунктами «Опубликовать…», «Импорт из файла…» и «Экспорт в Postman»Контекстное меню коллекции в Tetiva с пунктами «Опубликовать…», «Импорт из файла…» и «Экспорт в Postman»
Из контекстного меню импортированная коллекция ложится внутрь выбранной

Перед импортом открывается окно подтверждения. В нём видно, сколько в файле папок, запросов и примеров, куда встанет коллекция, какие окружения она добавит, на какие хосты ходят её запросы и что поменялось при разборе (раздел «Изменено при импорте»). Если внутри есть скрипты, окно покажет их текст, а импортируются они, только если отметить «Импортировать скрипты». По умолчанию галочка снята: раньше pm.environment.set из чужой коллекции мог при первой же отправке переписать ваш baseUrl. Скрипты Insomnia написаны на insomnia.*, Hoppscotch — часто на pw.* или hopp.*, и окно напомнит, что после импорта такие придётся переписать на pm.*. Скрипты Hoppscotch, уже написанные на pm.*, приходят без этого напоминания. Когда коллекцию кладут в папку со своей авторизацией, окно предупредит, что запросы без собственной авторизации её унаследуют. После импорта открывается вкладка новой коллекции.

«Импорт по ссылке…» забирает коллекцию со страницы share.tetiva.app по её ссылке или slug — так же, как кнопка «Открыть в Tetiva» на самой странице. Как это устроено и что проверяет окно подтверждения, описано на странице Публикация коллекции.

Insomnia, Hoppscotch, OpenAPI и HAR#

OpenAPI и Swagger. Подходят OpenAPI 3.0 и 3.1 и Swagger 2.0 в JSON или YAML. Первый тег операции становится папкой, а сама операция — запросом с именем из summary или operationId. Параметры пути превращаются в переменные {{имя}}, в запрос попадают обязательные query- и header-параметры и те, для которых в спецификации задано значение. JSON-тело берётся из примера или генерируется по схеме, авторизация — из security schemes (Bearer, Basic, Digest, API key, OAuth 2.0), а примеры ответов становятся примерами. Рядом появляется окружение с именем API: в нём baseUrl первого сервера, параметры пути и пустые места под учётные данные. Оно сразу становится активным, так что {{baseUrl}} подставится уже в первом запросе. Чего в коллекции не будет, окно подтверждения перечислит: внешние $ref, callbacks, webhooks, links, неподдержанные схемы авторизации.

Insomnia. Экспорт v4 в JSON или YAML и файлы v5 в YAML. Папки сохраняют вложенность и порядок. HTTP- и GraphQL-запросы приходят с заголовками, query- и path-параметрами, телом и авторизацией (basic, bearer, API key, OAuth 2.0, digest, AWS), WebSocket — с первым сообщением, gRPC — с сообщением и metadata. Выключенные заголовки и поля формы остаются выключенными, {{ _.name }} становится {{name}}. Каждое подокружение становится окружением Коллекция · Подокружение со значениями базового, вложенные значения получают имена через точку (limits.page), а секреты из vault приходят пустыми секретными переменными. Не переносятся теги шаблонов вроде {% response %} (они остаются текстом), .proto-файлы, заголовки и переменные папок, cookies, юнит-тесты и запросы Socket.IO.

Hoppscotch. Одна коллекция или файл Export all, GraphQL-коллекции тоже. Переезжают папки, тела, авторизация (basic, bearer, API key, digest, AWS, OAuth 2.0, JWT) и сохранённые ответы, которые становятся примерами. <<var>> превращается в {{var}}, заголовки коллекции и папок копируются в их запросы, а переменные коллекции и запросов собираются в окружение с именем коллекции, по одному на коллекцию. Окно подтверждения назовёт папки, которые в Hoppscotch выключали авторизацию: в Tetiva их запросы всё равно наследуют авторизацию родителя.

HAR. HAR-файл из DevTools браузера или прокси становится коллекцией с именем файла, а если хостов несколько — с папкой на каждый хост. Каждая запись файла превращается в запрос METHOD /path с адресом, заголовками и телом, ответ — в пример, где сохраняются тела JSON, XML и текст до 256 КБ. Служебные заголовки (Host, Content-Length, Accept-Encoding, Cookie, псевдозаголовки HTTP/2 и подобные) не переносятся. Записи не по HTTP, например WebSocket, и ресурсы страницы (картинки, скрипты, стили, шрифты) пропускаются с предупреждением. Окно подтверждения посчитает запросы, в которых остались учётные данные из HAR-файла, например заголовок Authorization или токен в query.

Что переносится из Postman#

Из PostmanВ Tetiva
Коллекция: имя, описание, authКоллекция верхнего уровня с теми же полями
Папки любой вложенностиВложенные коллекции
Запрос: имя, метод, URLЗапрос HTTP; неизвестный метод становится GET
Заголовки, в том числе с disabled: trueЗаголовки с выключенным флажком
raw + язык jsonТело JSON
raw + язык xml или htmlТело XML
raw с другим языком или без негоТело Raw
formdata и urlencodedФорма: ключ, значение, тип (text/file), флажок включения; у файловых полей нет файла — выберите его заново
fileТело binary без файла — его тоже нужно выбрать заново
graphqlЗапрос GraphQL: query, переменные, метод POST
Auth bearer, basic, apikey — на коллекции, папке или запросеСоответствующий тип авторизации
Auth oauth2, jwt, digest, awsv4Та же схема; грант authorization_code_with_pkce приезжает как Authorization Code
Запрос без блока authАвторизация наследуется от папки или коллекции; noauth становится No Auth
Скрипты prerequest и test на коллекции, папке и запросеPre-request и post-response скрипты — только с галочкой «Импортировать скрипты»
Сохранённые ответы (response)Примеры ответов запроса; пример с телом больше 256 КБ пропускается
Описание коллекции, папки и запросаОписание в Overview и на вкладке Docs
Переменные коллекции (variable)Окружение с именем коллекции; выключенные переменные остаются выключенными, secret — секретными

Query-параметры приезжают внутри URL; вкладка Params разбирает их из строки, так что таблица параметров заполняется сама. Скрипты Postman запускаются в песочнице Tetiva, где объект pm реализован частично, поэтому часть из них придётся поправить — см. Скрипты.

Что не переносится:

  • моки и мониторы;
  • схемы авторизации, которых в Tetiva нет — hawk, ntlm и прочие. Они становятся No Auth, но не пропадают молча: список виден в окне подтверждения, а после импорта висит уведомлением.

Строки в этом списке дословные, по одной на блок авторизации, а метка говорит, откуда он — из коллекции, папки или запроса:

  • request "Legacy service": auth type "ntlm" is not supported and was imported as no auth
  • … OAuth 2.0 grant "implicit" is not supported; pick one in the Auth tab
  • … the OAuth 2.0 block has an access token but no token URL; imported as a bearer token
  • … the JWT payload is not a JSON object and was dropped

В уведомлении показываются первые три, дальше приписывается (and N more). Что есть в приложении, перечислено на странице Авторизация.

Импорт окружения#

Окружение импортируется отдельным файлом: кнопкой импорта в окне «Окружения» (подсказка «Импорт окружения из Postman или Hoppscotch») или через «Импорт из файла…» в боковой панели. Окружение Postman получает имя из поля name внутри JSON, а не из имени файла, и файл с пустым name будет отклонён. Переменные приходят из массива values: выключенные остаются выключенными, запись с type: "secret" становится секретной, число, логическое значение или объект приходят своим JSON-текстом, а переменная без имени пропускается с предупреждением. Файл глобальных переменных Postman станет окружением с именем файла или «Globals»: глобального уровня в Tetiva нет. Если имя уже занято, к нему добавится номер — «Dev (2)».

Файл окружений Hoppscotch может содержать одно окружение или список. Секретные значения Hoppscotch выгружает пустыми, и Tetiva назовёт переменные, которые нужно заполнить. Файл больше 48 МБ не принимается, а коллекцию, выбранную вместо окружения, приложение узнает и подскажет импортировать её из боковой панели.

Экспорт#

«Экспорт в Postman» в контекстном меню коллекции собирает файл для всего поддерева: сама коллекция, вложенные коллекции, запросы, заголовки, тела, авторизация, скрипты и примеры ответов. Системный диалог предложит имя вида Имя коллекции.postman_collection.json. У окружения есть свой пункт «Экспорт в Postman» в окне «Окружения» — файл Имя.postman_environment.json, секретные переменные помечаются типом secret.

Границы формата стоит держать в голове: v2.1 описывает HTTP-запрос, поэтому gRPC-запросы при экспорте пропускаются с предупреждением, у WebSocket-запроса в файл попадают адрес и заголовки, но не сообщения, а тело типа binary — ссылка на файл на диске — в файл не попадает. Для переноса всей работы между машинами используйте синхронизацию, а не экспорт.

Импорт cURL вставкой#

Команду curl не нужно никуда импортировать — её вставляют прямо в строку URL открытого HTTP-запроса; в адресных строках gRPC и GraphQL вставка ничего не разбирает. Приложение разбирает её на метод, адрес, заголовки, тело и авторизацию и заполняет вкладки.

Уведомление перечисляет, что приехало: Imported from cURL: POST, 3 headers, existing authorization replaced. Про авторизацию оно пишет только тогда, когда она у запроса была и вставка её заменила или убрала. Запрос с Inherit остаётся на Inherit, если в команде нет -u или заголовка Authorization; если есть, авторизация из команды заменяет наследование, а уведомление говорит об этом и предлагает Undo.

Кнопка Undo появляется, только если вставке было что затирать — непустые включённые заголовки, тело или авторизацию. Тогда уведомление висит, пока его не закроют; в пустом запросе отменять нечего, и оно уходит само. Есть и второй способ его потерять: уведомление с Undo исчезает, как только вы поменяли что-то из вставленного — метод, адрес, заголовки, тело или авторизацию, — иначе отмена стёрла бы свежие правки.

Разбираются в том числе --digest и --aws-sigv4 'aws:amz:<region>:<service>', а заголовок x-amz-security-token сворачивается в поле Session Token. Если в команде есть и -u, и одна из этих схем, побеждает более специфичная: SigV4 сильнее digest, digest сильнее basic. Спорные места дописываются к уведомлению через тире:

  • --digest has no -u credentials; digest auth was not imported
  • --aws-sigv4 has no -u credentials; AWS signing was not imported
  • -u credentials replaced the Authorization header

Copy as и Generate code#

Рядом с кнопкой Send есть стрелка; такая же стоит у Query в GraphQL, у Invoke в gRPC и у Connect в WebSocket. В её меню:

  • Copy as cURL для HTTP и GraphQL, Copy as gRPCurl для gRPC, Copy as websocat и Copy as JavaScript для WebSocket;
  • для HTTP и GraphQL — подменю Copy as с Python (requests), JavaScript (fetch), Go, Java (HttpClient), Java (OkHttp), C# и PHP (Guzzle);
  • Generate code… — диалог, где код видно до того, как он попадёт в буфер.

Пункт Copy as копирует сразу: переменные {{var}} и значения секретов уже подставлены, код можно запускать как есть. В буфер попадает то, что сейчас в редакторе, вместе с несохранёнными правками. Копирование подтверждает уведомление. У Copy as cURL для HTTP-запроса предупреждения выводятся прямо в уведомлении, у остальных пунктов в нём указано их число, а кнопка Details открывает диалог Generate code на том же языке.

В диалоге Generate code — выбор языка, предпросмотр, список предупреждений и кнопка Copy. Он открывается на языке, который копировали последним; выбор запоминается отдельно для HTTP и GraphQL, для gRPC и для WebSocket. Что попадёт в код, решают два переключателя: Resolve variables (включён) подставляет активное окружение, а неизвестные переменные оставляет ссылками {{name}}; Include secret values (выключен) оставляет ссылками и секретные переменные, пока его не включить.

Copy as cURL для HTTP-запроса

Эта команда собирается тем же конвейером, что и реальная отправка, поэтому в буфере оказывается то, что ушло бы на сервер. Перед этим приложение сохраняет запрос, так что несохранённые правки в команду попадут:

  • переменные {{var}} уже подставлены;
  • заголовки отсортированы, многозначные повторяются несколькими -H;
  • cookie рабочего пространства для этого адреса добавляются флагом -b;
  • в multipart-форме файлы уходят как -F 'name=@путь', текстовые поля — как --form-string; urlencoded-форма и текстовое тело — как --data-raw, тело binary — как --data-binary @путь. Файл, имя которого просто написано в тексте, curl читать не станет;
  • pre-скрипт выполняется в режиме dry-run: его заголовки и переменные видны в команде, но в базу не сохраняются и записи в истории не создают. Если скрипт упал, ничего не копируется: уведомление пишет Not copied: the pre-request script of this request failed: …, а его кнопка Generate code… копирует команду без запуска скрипта;
  • Digest уходит как --digest -u 'user:pass', AWS Signature — как --aws-sigv4 'aws:amz:<region>:<service>' -u '<key>:<secret>', а при заданном session token добавляется -H 'x-amz-security-token: …';
  • за токеном OAuth 2.0 команда в сеть не ходит: берётся уже полученный. Если его нет, команда уйдёт без Authorization и с предупреждением no cached OAuth 2.0 token: the command carries no Authorization; get a token in the Auth tab first.

Остальные языки

Всё остальное — другие языки, cURL для GraphQL-запроса и любой язык в диалоге Generate code — собирает генератор сниппетов. Он берёт то, что открыто в редакторе, и ничего не отправляет:

  • авторизация применяется, OAuth 2.0 — только уже полученным токеном; Digest и AWS Signature V4 остаются комментарием;
  • cookie рабочего пространства для этого адреса уходят заголовком Cookie;
  • pre-скрипт не выполняется, и об этом есть предупреждение;
  • файлы из формы или тела binary упоминаются по имени и не читаются.

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

обновлено