Введение в Bruno API Client
Bruno — это революционный open-source API клиент, который использует принципиально другой подход к тестированию и разработке API. В отличие от традиционных облачных инструментов, Bruno хранит коллекции непосредственно в вашей файловой системе, используя язык разметки простого текста, что делает его по-настоящему Git-friendly и ориентированным на приватность. Эта файловая архитектура устраняет привязку к поставщику и обеспечивает беспрепятственную совместную работу через системы контроля версий.
Запущенный в 2022 году, Bruno быстро завоевал популярность среди разработчиков, разочарованных моделями подписки и зависимостью от облака. Он особенно привлекателен для команд, уже использующих рабочие процессы Git, и разработчиков, которые ценят суверенитет данных.
Почему Bruno Выделяется
Основная Философия и Преимущества
Архитектура Offline-First Bruno не требует облачной синхронизации или учетных записей. Все работает локально:
- Не требуется логин
- Полная конфиденциальность
- Работает без подключения к интернету
- Быстро и отзывчиво
Нативный Git Рабочий Процесс
Коллекции — это простые текстовые файлы (формат .bru
), которые бесшовно интегрируются с Git:
- Встроенный контроль версий
- Легкие code review для изменений API
- Разработка на основе веток
- Разрешение конфликтов слияния с помощью стандартных Git инструментов
Open Source и Бесплатный Лицензированный под MIT, Bruno действительно бесплатен без искусственных ограничений:
- Без платных тарифов или премиум функций
- Разработка, управляемая сообществом
- Прозрачная дорожная карта
- Расширяемая архитектура
Коллекции как Код
Формат файла .bru
читаем человеком и разработан для разработчиков:
meta {
name: Get User
type: http
seq: 1
}
get {
url: {{base_url}}/api/users/{{user_id}}
}
headers {
Authorization: Bearer {{token}}
Content-Type: application/json
}
vars:pre-request {
user_id: 123
}
tests {
test("Status code is 200", function() {
expect(res.status).to.equal(200);
});
test("Response has user data", function() {
expect(res.body).to.have.property('id');
expect(res.body).to.have.property('name');
});
}
Начало Работы с Bruno
Установка
Bruno доступен для всех основных платформ:
# macOS (Homebrew)
brew install bruno
# Windows (Chocolatey)
choco install bruno
# Linux (Snap)
snap install bruno
# Или скачать из GitHub releases
# https://github.com/usebruno/bruno/releases
Создание Первой Коллекции
- Создать Новую Коллекцию: File → New Collection
- Выбрать Расположение: Выберите папку в вашем Git репозитории
- Добавить Environment: Создайте файлы окружения для разных конфигураций
- Создать Requests: Правый клик на коллекцию → New Request
Структура Директории
my-api/
├── bruno.json # Metadata коллекции
├── environments/
│ ├── local.bru
│ ├── staging.bru
│ └── production.bru
└── requests/
├── auth/
│ ├── login.bru
│ └── refresh.bru
└── users/
├── get-user.bru
├── create-user.bru
└── update-user.bru
Понимание Формата .bru
Формат .bru
интуитивен и выразителен:
meta {
name: Create User
type: http
seq: 2
}
post {
url: {{base_url}}/api/users
}
headers {
Authorization: Bearer {{access_token}}
Content-Type: application/json
}
body:json {
{
"name": "{{user_name}}",
"email": "{{user_email}}",
"role": "developer"
}
}
vars:pre-request {
user_name: John Doe
user_email: john@example.com
}
script:pre-request {
// Генерация timestamp
bru.setVar("timestamp", Date.now());
// Установка кастомного заголовка
req.setHeader("X-Request-ID", bru.getVar("request_id"));
}
script:post-response {
// Сохранить user ID для последующих запросов
const userId = res.body.id;
bru.setEnvVar("created_user_id", userId);
// Логировать время ответа
console.log("Response time:", res.responseTime, "ms");
}
tests {
test("User created successfully", function() {
expect(res.status).to.equal(201);
expect(res.body.id).to.be.a('number');
});
}
Управление Окружениями
Файлы Окружений
Окружения Bruno — это простые файлы .bru
:
local.bru
vars {
base_url: http://localhost:3000
api_key: local-dev-key
debug: true
}
production.bru
vars {
base_url: https://api.production.com
api_key: {{process.env.PROD_API_KEY}}
rate_limit: 1000
}
Управление Секретами
Bruno интегрируется с переменными окружения системы для конфиденциальных данных:
vars {
database_url: {{process.env.DATABASE_URL}}
stripe_key: {{process.env.STRIPE_SECRET_KEY}}
}
Это предотвращает коммит секретов в Git при сохранении функциональности.
Продвинутые Возможности
Скриптинг и Автоматизация
Bruno поддерживает JavaScript в pre-request и post-response скриптах:
Pre-Request Script
// Генерация HMAC подписи
const crypto = require('crypto');
const message = req.getBody();
const secret = bru.getEnvVar('api_secret');
const signature = crypto
.createHmac('sha256', secret)
.update(message)
.digest('hex');
req.setHeader('X-Signature', signature);
Post-Response Script
// Извлечение и сохранение токена пагинации
if (res.body.next_page_token) {
bru.setVar('page_token', res.body.next_page_token);
}
// Условная логика
if (res.status === 401) {
// Токен истек, запустить обновление
console.log('Refreshing authentication token...');
}
Встроенный Фреймворк Тестирования
Bruno включает assertions в стиле Chai:
tests {
// Assertions кода статуса
test("Request successful", function() {
expect(res.status).to.be.oneOf([200, 201, 204]);
});
// Валидация времени ответа
test("Response time acceptable", function() {
expect(res.responseTime).to.be.below(500);
});
// Валидация JSON схемы
test("Valid user object", function() {
expect(res.body).to.have.all.keys('id', 'name', 'email');
expect(res.body.id).to.be.a('number');
expect(res.body.email).to.match(/.+@.+\..+/);
});
// Валидация header
test("Correct content type", function() {
expect(res.headers['content-type']).to.include('application/json');
});
}
Совместная Работа над Коллекциями
Рабочий Процесс на Основе Git
- Коммитить изменения API вместе с изменениями кода
- Создавать pull requests для модификаций API
- Просматривать изменения используя стандартные Git diff инструменты
- Конфликты слияния разрешаются текстовым редактором
Пример Git Рабочего Процесса
# Создать feature branch
git checkout -b feature/add-user-endpoints
# Внести изменения API в Bruno
# Закоммитить изменения
git add requests/users/
git commit -m "Add user CRUD endpoints"
# Push и создать PR
git push origin feature/add-user-endpoints
Code Review Изменений API
+ post {
+ url: {{base_url}}/api/users
+ }
+
+ body:json {
+ {
+ "name": "{{user_name}}",
+ "email": "{{user_email}}"
+ }
+ }
Миграция из Postman
Процесс Импорта
Bruno поддерживает импорт коллекций Postman. Если вы оцениваете различные инструменты тестирования API и сравниваете их возможности, возможность импорта Bruno делает переход бесшовным:
- Экспорт из Postman: Collection → Export → Collection v2.1
- Импорт в Bruno: Collection → Import → Select Postman JSON
- Проверка сопоставления: Проверить переменные окружения и скрипты
- Корректировка различий: Изменить скрипты при необходимости
Ключевые Различия для Понимания
Функция | Postman | Bruno |
---|---|---|
Хранилище | Облако | Файловая система |
Формат | JSON | .bru (текст) |
Синхронизация | Автоматическая | Git |
Цена | Freemium | Бесплатно |
Совместная работа | Встроенная | На основе Git |
Скрипты | Postman sandbox | Модули Node.js |
Workspaces | Облачные workspaces | Папки |
Миграция Скриптов
Скрипт Postman
pm.environment.set("token", pm.response.json().access_token);
pm.test("Status is 200", () => {
pm.response.to.have.status(200);
});
Эквивалент в Bruno
bru.setEnvVar("token", res.body.access_token);
test("Status is 200", function() {
expect(res.status).to.equal(200);
});
CLI и Автоматизация
Bruno CLI
Запускайте коллекции из командной строки:
# Установить CLI
npm install -g @usebruno/cli
# Запустить всю коллекцию
bru run --collection ./my-api
# Запустить конкретную папку
bru run --collection ./my-api --folder users
# Использовать конкретное окружение
bru run --collection ./my-api --env production
# Форматы вывода
bru run --collection ./my-api --output junit.xml --format junit
Интеграция CI/CD
Пример GitHub Actions
name: API Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install Bruno CLI
run: npm install -g @usebruno/cli
- name: Run API Tests
run: bru run --collection ./api-tests --env ci
env:
API_KEY: ${{ secrets.API_KEY }}
BASE_URL: ${{ secrets.BASE_URL }}
- name: Upload Results
uses: actions/upload-artifact@v3
with:
name: test-results
path: test-results.xml
Пример GitLab CI
api-tests:
stage: test
image: node:18
script:
- npm install -g @usebruno/cli
- bru run --collection ./api-tests --env staging
variables:
API_KEY: $STAGING_API_KEY
artifacts:
reports:
junit: test-results.xml
Поддержка GraphQL
Bruno нативно обрабатывает GraphQL запросы. Для команд, работающих с gRPC API, важно отметить, что Bruno фокусируется в первую очередь на REST и GraphQL:
meta {
name: Get User Posts
type: graphql
}
post {
url: {{graphql_endpoint}}
}
body:graphql {
query GetUserPosts($userId: ID!) {
user(id: $userId) {
id
name
posts(first: 10) {
edges {
node {
id
title
publishedAt
}
}
}
}
}
}
body:graphql:vars {
{
"userId": "{{user_id}}"
}
}
headers {
Authorization: Bearer {{graphql_token}}
}
Лучшие Практики
Организация Коллекций
Логическая Структура Папок
api-collection/
├── 01-authentication/
│ ├── login.bru
│ ├── logout.bru
│ └── refresh-token.bru
├── 02-users/
│ ├── list-users.bru
│ ├── get-user.bru
│ ├── create-user.bru
│ ├── update-user.bru
│ └── delete-user.bru
├── 03-posts/
└── 04-admin/
Соглашения об Именовании
- Используйте описательные имена:
create-user.bru
, а неuser1.bru
- Префикс с числами для упорядочивания:
01-login.bru
,02-get-profile.bru
- Используйте kebab-case для согласованности
Контроль Версий
Конфигурация .gitignore
# Игнорировать локальные переопределения окружения
environments/local.bru
# Игнорировать временные файлы
*.tmp
.bruno-cache/
# Сохранить отслеживаемое
!environments/*.example.bru
Содержательные Сообщения Коммита
git commit -m "Add user registration endpoint with validation"
git commit -m "Update auth flow to use refresh tokens"
git commit -m "Fix pagination in list users endpoint"
Безопасность
Переменные Окружения для Секретов
# Production environment
vars {
base_url: https://api.example.com
# Никогда не hardcode секреты
api_key: {{process.env.PROD_API_KEY}}
db_password: {{process.env.DB_PASSWORD}}
}
Пример Файла .env (git-ignored)
PROD_API_KEY=sk_live_xxxxxxxxxxxxx
DB_PASSWORD=super_secret_password
STRIPE_KEY=sk_live_xxxxxxxxxxxxx
Устранение Неполадок
Распространенные Проблемы
Коллекции Не Загружаются
- Проверить, что
bruno.json
существует в корне коллекции - Проверить разрешения файлов
- Убедиться, что файлы .bru используют правильный синтаксис
Переменные Окружения Не Разрешаются
- Проверить, что окружение выбрано
- Проверить написание имени переменной
- Для переменных
process.env
убедиться, что они экспортированы
Скрипты Не Выполняются
- Проверить на ошибки синтаксиса JavaScript
- Проверить, что модули Node.js доступны
- Просмотреть вывод консоли на наличие сообщений об ошибках
Оптимизация Производительности
Большие Коллекции
- Разделить на несколько коллекций
- Использовать организацию папок
- Выборочная загрузка в CLI
Время Ответа
- Мониторить сетевые условия
- Проверить конфигурации таймаута
- Использовать connection pooling для массовых запросов
Сравнение: Bruno vs Конкуренты
При выборе API клиента стоит сравнить Bruno с альтернативами, такими как Insomnia REST client:
Функция | Bruno | Postman | Insomnia | Thunder Client |
---|---|---|---|---|
Стоимость | Бесплатно | Freemium | Freemium | Бесплатно + Pro |
Offline | Да | Ограничено | Да | Да |
Хранилище | Локальные файлы | Облако | Гибридное | Workspace VS Code |
Git-friendly | Отлично | Плохо | Умеренно | Хорошо |
Совместная работа | На основе Git | Встроенная | Платно | Ограниченная |
Кривая Обучения | Низкая | Средняя | Низкая | Очень Низкая |
Расширяемость | Скрипты | Скрипты + Apps | Плагины | Ограниченная |
Заключение
Bruno API Client представляет собой смену парадигмы в инструментах тестирования API, приоритизируя рабочие процессы разработчиков, владение данными и простоту. Его файловая архитектура идеально согласуется с современными практиками разработки, ориентированными на Git, что делает его идеальным выбором для команд, уже освоивших контроль версий.
Open-source природа обеспечивает прозрачность, инновации, управляемые сообществом, и свободу от vendor lock-in. Хотя ему может не хватать некоторых продвинутых функций, найденных в устоявшихся инструментах, таких как Postman, фокус Bruno на основной функциональности и опыте разработчика делает его все более привлекательным для команд, ищущих легкую, ориентированную на приватность альтернативу.
Независимо от того, мигрируете ли вы из Postman, начинаете с нуля с тестированием API или ищете лучшую интеграцию с вашим Git рабочим процессом, Bruno предлагает убедительное, экономически эффективное решение, которое ставит разработчиков на первое место.