Postman, Insomnia, Bruno и мой Kurlo: как я написал API‑клиент на Go и чем он отличается

В апреле здесь вышла статья «Кризис инструментария API». Автор перечислил всё, за что разработчики не любят Postman и его наследников, и закончил мыслью, что лучший инструмент, наверно, ещё не создан. Может быть, его напишете вы.

Я как раз писал в то время. Из главного, Kurlo — мой собственный проект. Код открыт, платного тарифа нет и не задумывается.

Делал я его для себя, под свою ежедневную работу, и да, я еще пользуюсь API‑клиентами в эпоху харнессов. Поэтому в нём нет того, ради чего обычно хотелось уйти или часто триггерило: аккаунта, облачных воркспейсов, тарифной сетки, телеметрии на каждый шаг. Каждая функция появилась потому, что мне или друзьям, в том числе QA, её не хватало. Идея статьи такова: инструмент получился, им пользуемся не только мы, и хочется, чтобы о нём узнало больше людей. Может быть, кому‑то он подойдёт так же, как подошёл мне и решит чью‑то боль.

Ниже расскажу, как он устроен, где выигрывает у Postman, Insomnia и Bruno, а где пока проигрывает. Отдельный раздел — для тестировщиков: тесты, прогон коллекций по CSV, моки и нагрузочные тесты на k6, и всё это можно запускать в CI. В конце — про версию 3.0, которая вышла 7 ноября.

Почему не взял готовый вариант

За всё время разработки пользовался только Postman, но с какого‑то момента мой ноут начал сильно греться, а когда локально было запущено несколько приложений, ещё и часто виснуть и лагать вплоть до перезапуска. Работать стало некомфортно, и я начал смотреть на аналоги. Заодно выяснилось, что Postman за это время стал ещё и дорогим, раньше с друзьями пользовались платной версией для команд (да, мы существуем).

С марта 2026 года бесплатный Postman рассчитан на одного пользователя. Команда из трёх человек платит $19 за каждого в месяц, это $684 в год за то, чтобы делиться запросами. Native Git, о котором много писали весной, формально есть и на Free, но работа вместе всё равно упирается в командный тариф.

Insomnia бесплатно даёт Git Sync максимум трём пользователям и 1000 запросов к мок‑серверу в месяц. Для всего, кроме Scratch Pad, нужен аккаунт.

Bruno ближе всех к тому, что я хотел: коллекции лежат файлами в репозитории, аккаунта нет. Но в бесплатной версии он работает только с публичными Git‑провайдерами, коммит и push из приложения — в Pro, воркспейсов два, прогон коллекции по CSV‑файлу тоже платный. Приватный GitLab на работе — и ты уже в Pro за $6.

Отдельно скажу про Yaak. Его делает Грегори Шир, автор Insomnia, уже после того, как Insomnia купила Kong. Технически Yaak ближе всех к Kurlo: Tauri и Rust вместо Electron, тоже системный WebView, работает офлайн. Воркспейс он хранит в папке как YAML, и Git у него встроенный: ветки, коммиты, push и pull прямо из приложения. С протоколами и авторизацией всё вроде бы хорошо, есть CLI и MCP‑сервер.

Но Yaak сознательно остаётся клиентом для отправки запросов, а не для тестирования. Скриптов в нём нет, в документации так и написано, вместо них шаблонные теги и цепочки запросов. Раннера коллекций в интерфейсе тоже нет (пачку запросов можно отправить из CLI), прогона по CSV нет, мок‑сервера я в документации не нашёл. Если в ваших коллекциях лежат логика на pm.* и тесты, переносить их некуда. Плюс лицензия: код открыт под MIT, но готовые сборки бесплатны только для личного использования. На работе нужна лицензия: $79 в год для одного человека или $149 за пользователя в год для компании.

Были и другие варианты. Hoppscotch живёт в браузере, и для локальной коллекции в репозитории это неудобно. HTTP Client в IDE от JetBrains хорош, но коллегам‑тестировщикам ставить ради него IDE никто не будет. Curl никуда не делся, но хранить сорок запросов с авторизацией и тестами в shell‑скриптах вряд ли кто‑то станет.

Также вернусь к памяти. Postman, Insomnia и Bruno написаны на Electron, и каждый тащит с собой целый Chromium. Когда рядом крутятся бэкенд, база и пара контейнеров, это чувствуется. Об этом чуть ниже, с цифрами.

Коллекция — это папка с YAML

Главное решение, на котором держится всё остальное: в Kurlo нет своей базы и нет облака. Один запрос — один YAML‑файл. Окружения, переменные, мок‑примеры, нагрузочные сценарии лежат рядом в той же папке. Открыли папку из репозитория — получили коллекцию. Склонировал коллега репозиторий — получил её целиком, вместе с тестами.

Вот как выглядит запрос на диске (немного сократил):

version: 1request: name: List orders requestType: http method: GET url: '{{baseUrl}}/orders?limit=20' auth: type: bearer bearerToken: '{{kurloSecret:request.1bf039f0-….auth.bearerToken}}' testScriptJs: |- pm.test("status is 200", () => { pm.response.to.have.status(200); });

Обратите внимание на токен. Секретов в YAML нет: вместо значения стоит плейсхолдер, а само значение лежит в зашифрованном профиле на вашем пк (AES-256-GCM, ключ в системном keychain). Коллега, склонировавший репозиторий, получит структуру коллекции, но не ваш токен — свой он введёт сам. Недавно здесь была статья о том, как команда чуть не закоммитила токены в открытом виде, выгружая коллекцию в Git вручную. В Kurlo эта проблема решена на уровне формата файла.

Поскольку всё лежит файлами, ревью коллекции идёт в том же pull request, что и изменение API. Бэкендер поменял формат ответа, поправил тест в коллекции, ревьюер видит оба изменения в одном диффе. Делиться можно через любой Git‑хостинг, включая приватный GitLab, без ограничения по числу людей.

Редактор запроса: тело в JSON, ответ 200 OK, тест пройден, внизу ветка и счётчик измененийОбычный редактор запроса. Внизу слева — текущая ветка и два изменённых файла

Git встроен в приложение: дифф по файлам, коммит, история, ветки, pull и push. Если ветка уже запушена, оттуда же открывается pull request на GitHub или merge request на GitLab. Можно этим не пользоваться и работать из терминала, как привыкли, — Kurlo подхватит изменения файлов сам.

Git-экран: список изменённых файлов, дифф Login.yml, кнопка PushGit‑экран. Слева изменённые файлы, справа дифф

Скрипты из Postman работают как есть

Новый API‑клиент никому не нужен, если для перехода придётся переписывать скрипты (да, мы пользовались скриптами, потому что удобно). У большинства команд в коллекциях Postman лежит логика: достать токен из ответа, положить в переменную, проверить схему. На Хабре про Bruno пишут именно такие вещи: импорт из Postman кривой, скрипты ломаются, потому что у Bruno своя песочница и свой bru.*.

Я пошёл другим путём и стал исполнять pm.* как есть. Работают pm.test, pm.expect с синтаксисом chai, pm.sendRequest, pm.variables, pm.environment, CryptoJS, require для lodash, ajv и uuid и даже старые tests[] и postman.setEnvironmentVariable. Скрипты не конвертируются, поэтому один и тот же файл может жить и у вас в Kurlo, и у коллеги, который пока остался в Postman (как мой друг, но я обязательно его переведу в Kurlo).

Окно импорта: Bruno, Postman, Insomnia, OpenAPI, OpenAPI по ссылке, HAR, .http-файлыОткуда можно импортировать. Последний пункт — файлы.http от JetBrains HTTP Client и VS Code REST Client

Импорт есть из Postman (коллекции, окружения, глобальные переменные), Insomnia, Bruno, OpenAPI и Swagger, в том числе по ссылке на спецификацию, HAR из DevTools, .http‑файлов и curl из буфера. Экспорт — обратно в Postman v2.1 и OpenAPI, так что уйти из Kurlo так же просто, как прийти.

Почему не Electron и что с памятью

Kurlo написан на Wails: бэкенд на Go, интерфейс на Svelte 5 в системном WebView. На macOS это WKWebView, на Windows — WebView2, на Linux — WebKitGTK. Своего Chromium в установщике нет, поэтому размеры выглядят так (Kurlo 3.0.0, проверял 23 октября):

Загрузка

macOS

Windows

Linux

Kurlo

25 МБ

15 МБ

13 МБ

Bruno

160 МБ

117 МБ

167 МБ

Postman

197 МБ

204 МБ

199 МБ

Insomnia

363 МБ

501 МБ

591 МБ

В комментариях к одной из статей достаточно логично заметили, что Bruno — тоже веб‑обёртка. Kurlo, очевидно, тоже: интерфейс рендерит браузерный движок, просто системный. Поэтому чуда с памятью не будет. Сейчас, когда я пишу эту статью, Kurlo с открытой коллекцией занимает около 220 МБ вместе с процессами WebKit на macOS. Выигрыш в другом: в размере загрузки, в быстром старте и в том, что запросы отправляет Go, а не Node.js внутри Electron. HTTP/2, прокси, mTLS и редиректы — это стандартный net/http.

Протоколы и авторизация

Кроме HTTP есть GraphQL, WebSocket, Socket.IO, SSE, gRPC (унарные вызовы и стриминг) и MCP: укажите адрес MCP‑сервера, и Kurlo покажет его инструменты и сырой обмен JSON‑RPC. Из авторизаций — Bearer, Basic, Digest, API Key, OAuth 1.0 и 2.0 (с входом через браузер и автообновлением токена), AWS SigV4, NTLM и клиентские сертификаты.

Kurlo для тестирования

Большинство API‑клиентов хороши в одном: отправить запрос и показать ответ. Тестировщику этого обычно мало. Нужно проверить ответы, прогнать всю коллекцию на нескольких наборах данных, подменить сервис, которого ещё нет, посмотреть, что будет под нагрузкой, и запустить всё это в CI. Обычно это пять разных инструментов. В Kurlo всё это в одном приложении и в тех же YAML‑файлах, что и запросы.

Тесты и раннер коллекций

Тесты пишутся в том же синтаксисе, что и в Postman: pm.test, pm.expect с chai, pm.response. Их можно повесить на запрос, на папку или на всю коллекцию. Например, проверку «статус не 5 xx и ответ пришёл быстрее секунды» удобно один раз положить на коллекцию, а не копировать в каждый запрос.

Раннер прогоняет коллекцию или папку целиком. Запросы можно отфильтровать по тегам: например, перед релизом гонять только smoke, а медленные с тегом slow пропускать. Порядок — по одному или параллельно, с задержкой между запросами и любым числом итераций. Если подложить CSV или JSON, каждая строка станет отдельной итерацией со своими переменными, а в скриптах она доступна через pm.iterationData. По итогам можно скачать HTML‑отчёт.

Раннер коллекций: выбор коллекции, фильтр по тегам, CSV, порядок запуска, результат PassedРаннер: слева что и как запускать, справа результат

Прогон по файлу с данными — как раз та функция, за которую другие API‑клиенты просят деньги. В Postman она доступна с тарифа Solo, в Bruno — в Pro.

Мок‑сервер

Ответ, который вы сохранили как example, уже является маршрутом. Мок‑сервер раздаёт такие примеры на localhost: учитывает метод, шаблон пути вроде /orders/:id и параметры запроса и умеет воспроизводить задержку. В логе видны все входящие запросы, в том числе те, которым не нашлось примера. На такой запрос мок отвечает 404 и перечисляет маршруты, которые у него есть.

Скриншот: мок‑серверМок-сервер на порту 3100: маршрут из примера и лог с одним найденным и одним ненайденным запросом

Аккаунт не нужен, лимита на число запросов нет. Для сравнения: в Insomnia на бесплатном тарифе 1000 запросов к мокам в месяц, у Postman моки живут в облаке.

Нагрузочные тесты на k6

Эта часть появилась в версии 2.6. Мне не хотелось писать собственный генератор нагрузки, когда есть k6, поэтому Kurlo собирает сценарий из запросов коллекции и генерирует скрипт k6, а нагрузку создаёт сам k6, установленный заранее.

Начать можно с любого запроса: в его меню есть пункт «Load test this request». Можно взять сразу всю коллекцию или папку. Дальше собирается сценарий. Логин помечается как шаг «один раз на пользователя», из ответа достаётся токен (JSON path вроде $.access_token, заголовок или регулярка) и подставляется в следующие шаги как {{token}}. На каждый шаг можно добавить проверки: статус, наличие поля в JSON, текст в теле. Есть паузы между шагами, в том числе случайные, чтобы виртуальные юзеры не били в сервер параллельно.

Сценарий нагрузочного теста: логин один раз на пользователя, сохранение токена, список заказов на каждой итерацииСценарий: логин один раз на пользователя, дальше итерации с проверками

Профиль нагрузки выбирается из пресетов: smoke, load, stress, spike и soak, — или задаётся вручную. Можно держать фиксированное число виртуальных пользователей, а можно задать число итераций в секунду. Критерии прохождения пишутся почти обычными словами: p95 времени ответа меньше 500 мс, ошибок меньше 1%, проверок пройдено больше 99%. Если критерий нарушен, прогон считается проваленным, а при желании k6 остановит его досрочно. CSV тоже работает: например, каждому виртуальному пользователю выдаётся своя строка с логином.

Скриншот: профиль нагрузки и критерииПрофиль нагрузки со ступенчатым разгоном и порогами по времени ответа, ошибкам и проверкам

После прогона видно, какие критерии выполнены и с каким запасом, сколько было запросов, какой p95 и p99 у каждого шага. Отсюда же открывается HTML‑отчёт самого k6.

Результат: все критерии выполнены, 10 050 запросов, p95 212 мс, разбивка по шагам Login и List ordersРезультат прогона на 50 пользователей. Шаг с ошибками подсвечен

Скрипт можно выгрузить и дальше жить без Kurlo: это обычный файл для k6, без привязки к приложению. Секреты в него по умолчанию не попадают, их передают через переменные окружения при запуске. Перед прогоном на любой адрес, кроме localhost, Kurlo показывает, по каким хостам пойдёт нагрузка, и просит подтвердить. Для защищённого окружения нужно вручную ввести имя хоста, чтобы случайно не положить прод (да, с таким мы тоже столкнулись).

Чего тут нет: скрипты запросов в k6 не переводятся (для нагрузки есть свои проверки и извлечение значений), а хранится только последний результат, без истории и сравнения с предыдущим прогоном.

Всё это в CI

Для CI есть консольная версия на npm. Она прогоняет коллекцию с тестами, умеет данные из CSV, пишет отчёты в JUnit и JSON и возвращает код 1, если хоть одна проверка не прошла:

npx -y @kurlo/cli run ./workspace --env CI --data users.csv  --reporter-junit-export report.xml

Нагрузочный тест, собранный в приложении, запускается той же утилитой. Если пороги не выполнены, она выходит с кодом 99, а отчёт k6 всё равно сохраняется:

kurlo load run "Checkout flow" --workspace ./api --env CI --report report.html

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

Сравнение в одной таблице

Цены и ограничения проверены 8 ноября 2026 года на страницах тарифов. Если что‑то поменялось, напишите — поправлю.

Что сравниваем

Kurlo

Postman

Insomnia

Bruno

Бесплатно для команды

да, без лимита

1 пользователь

Git Sync до 3 человек

да, но только публичный Git

Платный тариф

нет

$9 Solo, $19 Team

$12 Pro, $45 Enterprise

$6 Pro, $11 Ultimate

Аккаунт

не нужен

нужен для коллекций

нужен, кроме Scratch Pad

не нужен

Где коллекции

YAML в вашем репо

облако или Native Git

облако, локально или Git

файлы в вашем репо

Скрипты Postman

как есть

родные

слой совместимости

конвертируются в bru.*

Прогон по CSV/JSON

бесплатно

с тарифа Solo

есть

в Pro

Нагрузочные тесты

k6, локально и в CI

локальные на Free, облачные платно

нет

нет

Мок‑сервер

локальный, без лимита

в облаке

1000 запросов в месяц

локальный

Проверка CORS/CSP

есть

нет

нет

нет

MCP

клиент и сервер

клиент

клиент

от сообщества

Исходный код

MIT

закрыт

Apache-2.0

MIT, платные редакции сверху

Основа

Go + системный WebView

Electron

Electron

Electron

Где Kurlo пока хуже

Статья без этого раздела была бы рекламой, так что честно.

У Postman есть общие облачные воркспейсы, мониторы по расписанию и публикуемая документация API. Если ваша команда живёт в облаке Postman и это её устраивает, переходить незачем. Insomnia сильна в design‑first работе с OpenAPI и интеграции с Kong. Bruno старше Kurlo, у него большое сообщество, частые релизы, расширение для VS Code и интеграции с менеджерами секретов.

Kurlo не умеет MQTT и SOAP. В скриптах нет setTimeout и async/await: движок исполняет синхронный JavaScript, и для большинства сценариев из Postman этого хватает, но не для всех. postman.setNextRequest и визуализаторы (pm.visualizer.set) тоже пока не поддерживаются. Ну и главное: мой проект все же молодой, первый публичный релиз вышел в июле, хотя разрабатывал я его около полугода до релиза.

Агент снаружи: kurlo mcp

Большинство сейчас пишет код вместе с Claude Code и Codex, в том числе и я, поэтому в какой‑то момент захотел, чтобы агент мог пользоваться моей коллекцией, да и это де‑факто стандарт, почти все приложения имеют mcp в наше время. Так появился kurlo mcp‑MCP‑сервер, который отдаёт агенту воркспейс Kurlo.

Агент может запустить сохранённый запрос с его авторизацией и тестами, создать новый запрос, дописать тесты, посмотреть историю и объяснить, почему последний запрос упал. Секреты при этом уходят в API, но модель видит вместо них [secret]. Окружение можно пометить как защищённое, и тогда агент не отправит в него ни одного запроса: прод остаётся по сути закрытым.

Подключить сервер ко всем клиентам на машине — Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI — можно командой kurlo mcp install. В официальном MCP Registry он лежит под именем dev.kurlo/kurlo.

Kurlo 3.0: агент внутри приложения

7 ноября вышла версия 3.0, которая решала вопрос: а зачем нужен API‑клиент, если сейчас буквально всю работу делают через харнессы? MCP‑сервер — это агент снаружи, в терминале. В 3.0 появился Agent mode: тот же агент, но прямо в окне Kurlo.

Пишете в чат обычным языком: «добавь тест на статус к List orders», «почему упал последний запрос», «прогони коллекцию на Staging и разбери ошибки», «импортируй вот эту спецификацию»,«создай нагрузочный тест на коллекцию..». Агент делает это инструментами Kurlo: читает и запускает запросы, правит YAML, гоняет раннер и нагрузочные тесты, поднимает мок‑сервер.

Модель на выбор любая, какая у вас есть. Можно войти через OpenRouter, добавить свой ключ Anthropic, OpenAI или любого OpenAI‑совместимого сервера, взять локальную модель из Ollama. А если у вас уже есть подписка на Claude Code или Codex, Kurlo подключит их CLI с вашим же аккаунтом, и платить отдельно за API не придётся в целом.

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

Каждое изменение файлов и каждый запрос, кроме GET, HEAD и OPTIONS, ждёт подтверждения. Агент показывает карточку с тем, что именно поменяется, дифф открывается по клику, а вы нажимаете Apply или Reject. Если задача большая, агент сначала предлагает план. Вы одобряете его один раз, и шаги из плана он уже не согласовывает по отдельности, а всё, что за его пределами, — по‑прежнему спрашивает, вообщем все как в обычных харнессах, но применимо к Kurlo.

Агент добавил тест к List orders и ждёт ответа: Apply, Allow for this chat, RejectКарточка подтверждения: какой файл, что изменится, дифф по клику

Агента можно посадить в отдельную Git‑ветку. Тогда он коммитит туда после каждого шага, и его работа ревьюится как обычный pull request. Ещё он умеет подключать ваши MCP‑серверы, а секреты, как и в kurlo mcp, видит только как [secret].

Все вызовы инструментов записываются во вкладку Activity: какой инструмент, с какими аргументами, какие файлы изменил. Рядом с каждым файлом есть кнопка Restore, если передумали. Чаты хранятся в зашифрованном виде у вас на компьютере и никуда не отправляются, кроме выбранной вами модели.

Activity: список вызовов инструментов, дифф изменений и кнопка RestoreActivity: всё, что агент сделал, с возможностью откатитьТот же чат, но отвечает Codex: видны лимиты подписки и заполненность контекстаЗдесь в роли агента Codex со своим аккаунтом и лимитами тарифа

Дальше в планах — запуск агента из терминала и в CI с теми же инструментами, GitHub Action поверх него, упоминания запросов через @ в чате и автодополнение в скриптах.

Я не пытаюсь убедить всех срочно уходить с Postman. Kurlo вырос из моих собственных задач, и если ваши на них похожи — попробуйте. Если нет, мне всё равно будет интересно узнать в комментариях, чего вам не хватает в вашем нынешнем клиенте, если вы им еще пользуетесь.

Скачать Kurlo для macOS, Windows и Linux можно на kurlo.dev, исходники — на GitHub. Если что‑то не заработает при переезде с Postman или других клиентов, а также возможно есть идеи по улучшению, создайте issue, или отпишите в комментарии — и я постараюсь ответить.

Ссылки

  • Репозиторий: github.com/stormhop/kurlo

  • Документация и загрузки: kurlo.dev

  • Agent mode: kurlo.dev/agent

  • Переезд с Postman, Insomnia и Bruno: kurlo.dev/docs/getting‑started/migrating

  • CLI: @kurlo/cli на npm

Источник: habr.com

0 0 голоса
Рейтинг новости
1
0
Подписаться
Уведомить о
0 комментариев