Введение в 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

Создание Первой Коллекции

  1. Создать Новую Коллекцию: File → New Collection
  2. Выбрать Расположение: Выберите папку в вашем Git репозитории
  3. Добавить Environment: Создайте файлы окружения для разных конфигураций
  4. Создать 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

  1. Коммитить изменения API вместе с изменениями кода
  2. Создавать pull requests для модификаций API
  3. Просматривать изменения используя стандартные Git diff инструменты
  4. Конфликты слияния разрешаются текстовым редактором

Пример 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 делает переход бесшовным:

  1. Экспорт из Postman: Collection → Export → Collection v2.1
  2. Импорт в Bruno: Collection → Import → Select Postman JSON
  3. Проверка сопоставления: Проверить переменные окружения и скрипты
  4. Корректировка различий: Изменить скрипты при необходимости

Ключевые Различия для Понимания

ФункцияPostmanBruno
ХранилищеОблакоФайловая система
Формат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:

ФункцияBrunoPostmanInsomniaThunder Client
СтоимостьБесплатноFreemiumFreemiumБесплатно + 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 предлагает убедительное, экономически эффективное решение, которое ставит разработчиков на первое место.