Introducción a Bruno API Client
Bruno es un revolucionario cliente API de código abierto que adopta un enfoque fundamentalmente diferente para el testing y desarrollo de APIs. A diferencia de las herramientas tradicionales basadas en la nube, Bruno almacena colecciones directamente en tu sistema de archivos usando lenguaje de marcado de texto plano, haciéndolo verdaderamente compatible con Git y enfocado en la privacidad. Esta arquitectura basada en archivos elimina el vendor lock-in y permite colaboración fluida a través de sistemas de control de versiones.
Lanzado en 2022, Bruno rápidamente ganó tracción entre desarrolladores frustrados con modelos de precios por suscripción y dependencia de la nube. Es particularmente atractivo para equipos que ya usan flujos de trabajo Git y desarrolladores que valoran la soberanía de datos.
Si estás explorando opciones de clientes API, te recomendamos revisar nuestra comparación completa de alternativas a Postman y el análisis de herramientas API para 2025. Para entender cómo Bruno se compara con otras opciones ligeras, consulta nuestra guía sobre Thunder Client para VS Code.
Por Qué Bruno Destaca
Filosofía Central y Ventajas
Arquitectura Offline-First Bruno no requiere sincronización en la nube ni cuentas. Todo se ejecuta localmente:
- No requiere login
- Privacidad completa
- Funciona sin conexión a internet
- Rápido y responsivo
Flujo de Trabajo Nativo de Git
Las colecciones son archivos de texto plano (formato .bru) que se integran perfectamente con Git:
- Control de versiones incorporado
- Revisiones de código fáciles para cambios de API
- Desarrollo basado en branches
- Resolución de conflictos de merge usando herramientas Git estándar
Open Source y Gratuito Licenciado bajo MIT, Bruno es verdaderamente gratuito sin limitaciones artificiales:
- Sin tiers pagos ni características premium
- Desarrollo impulsado por la comunidad
- Roadmap transparente
- Arquitectura extensible
Colecciones como Código
El formato de archivo .bru es legible por humanos y diseñado para desarrolladores:
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');
});
}
Comenzando con Bruno
Instalación
Bruno está disponible para todas las plataformas principales:
# macOS (Homebrew)
brew install bruno
# Windows (Chocolatey)
choco install bruno
# Linux (Snap)
snap install bruno
# O descarga desde GitHub releases
# https://github.com/usebruno/bruno/releases
Creando Tu Primera Colección
- Crear Nueva Colección: File → New Collection
- Elegir Ubicación: Selecciona una carpeta en tu repositorio Git
- Agregar Environment: Crea archivos de entorno para diferentes configuraciones
- Crear Requests: Clic derecho en colección → New Request
Estructura de Directorio
my-api/
├── bruno.json # Metadata de colección
├── environments/
│ ├── local.bru
│ ├── staging.bru
│ └── production.bru
└── requests/
├── auth/
│ ├── login.bru
│ └── refresh.bru
└── users/
├── get-user.bru
├── create-user.bru
└── update-user.bru
Entendiendo el Formato .bru
El formato .bru es intuitivo y expresivo:
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 {
// Generar timestamp
bru.setVar("timestamp", Date.now());
// Establecer header personalizado
req.setHeader("X-Request-ID", bru.getVar("request_id"));
}
script:post-response {
// Guardar user ID para requests subsecuentes
const userId = res.body.id;
bru.setEnvVar("created_user_id", userId);
// Log response time
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');
});
}
Gestión de Entornos
Archivos de Entorno
Los entornos de Bruno son archivos .bru simples:
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
}
Gestión de Secretos
Bruno se integra con variables de entorno del sistema para datos sensibles:
vars {
database_url: {{process.env.DATABASE_URL}}
stripe_key: {{process.env.STRIPE_SECRET_KEY}}
}
Esto previene que los secretos sean commiteados a Git mientras se mantiene la funcionalidad.
Características Avanzadas
Scripting y Automatización
Bruno soporta JavaScript en scripts pre-request y post-response:
Pre-Request Script
// Generar firma 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
// Extraer y guardar token de paginación
if (res.body.next_page_token) {
bru.setVar('page_token', res.body.next_page_token);
}
// Lógica condicional
if (res.status === 401) {
// Token expirado, trigger refresh
console.log('Refreshing authentication token...');
}
Framework de Testing Incorporado
Bruno incluye assertions estilo Chai:
tests {
// Assertions de código de estado
test("Request successful", function() {
expect(res.status).to.be.oneOf([200, 201, 204]);
});
// Validación de tiempo de respuesta
test("Response time acceptable", function() {
expect(res.responseTime).to.be.below(500);
});
// Validación de esquema 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(/.+@.+\..+/);
});
// Validación de header
test("Correct content type", function() {
expect(res.headers['content-type']).to.include('application/json');
});
}
Colaboración en Colecciones
Flujo de Trabajo Basado en Git
- Commitear cambios de API junto con cambios de código
- Crear pull requests para modificaciones de API
- Revisar cambios usando herramientas Git diff estándar
- Conflictos de merge resueltos con editor de texto
Ejemplo de Flujo de Trabajo Git
# Crear feature branch
git checkout -b feature/add-user-endpoints
# Hacer cambios de API en Bruno
# Commitear cambios
git add requests/users/
git commit -m "Add user CRUD endpoints"
# Push y crear PR
git push origin feature/add-user-endpoints
Code Review de Cambios de API
+ post {
+ url: {{base_url}}/api/users
+ }
+
+ body:json {
+ {
+ "name": "{{user_name}}",
+ "email": "{{user_email}}"
+ }
+ }
Migración desde Postman
Proceso de Importación
Bruno soporta importar colecciones Postman. Si estás evaluando diferentes herramientas de testing de API y comparando sus características, la capacidad de importación de Bruno hace que el cambio sea fluido:
- Exportar desde Postman: Collection → Export → Collection v2.1
- Importar a Bruno: Collection → Import → Select Postman JSON
- Revisar mapeo: Verificar variables de entorno y scripts
- Ajustar diferencias: Modificar scripts si es necesario
Diferencias Clave a Entender
| Característica | Postman | Bruno |
|---|---|---|
| Almacenamiento | Cloud | Sistema de archivos |
| Formato | JSON | .bru (texto) |
| Sync | Automático | Git |
| Precio | Freemium | Gratis |
| Colaboración | Incorporada | Basada en Git |
| Scripts | Sandbox Postman | Módulos Node.js |
| Workspaces | Cloud workspaces | Carpetas |
Migración de Scripts
Script de Postman
pm.environment.set("token", pm.response.json().access_token);
pm.test("Status is 200", () => {
pm.response.to.have.status(200);
});
Equivalente en Bruno
bru.setEnvVar("token", res.body.access_token);
test("Status is 200", function() {
expect(res.status).to.equal(200);
});
CLI y Automatización
Bruno CLI
Ejecuta colecciones desde línea de comandos:
# Instalar CLI
npm install -g @usebruno/cli
# Ejecutar colección completa
bru run --collection ./my-api
# Ejecutar carpeta específica
bru run --collection ./my-api --folder users
# Usar entorno específico
bru run --collection ./my-api --env production
# Formatos de output
bru run --collection ./my-api --output junit.xml --format junit
Integración CI/CD
Ejemplo 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
Ejemplo 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
Soporte GraphQL
Bruno maneja requests GraphQL nativamente. Para equipos que trabajan con APIs gRPC, es importante notar que Bruno se enfoca principalmente en REST y 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}}
}
Mejores Prácticas
Organización de Colecciones
Estructura de Carpetas Lógica
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/
Convenciones de Nomenclatura
- Usa nombres descriptivos:
create-user.brunouser1.bru - Prefijo con números para ordenar:
01-login.bru,02-get-profile.bru - Usa kebab-case para consistencia
Control de Versiones
Configuración .gitignore
# Ignorar overrides locales de entorno
environments/local.bru
# Ignorar archivos temporales
*.tmp
.bruno-cache/
# Mantener tracked
!environments/*.example.bru
Mensajes de Commit Significativos
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"
Seguridad
Variables de Entorno para Secretos
# Production environment
vars {
base_url: https://api.example.com
# Nunca hardcodear secretos
api_key: {{process.env.PROD_API_KEY}}
db_password: {{process.env.DB_PASSWORD}}
}
Ejemplo Archivo .env (git-ignored)
PROD_API_KEY=sk_live_xxxxxxxxxxxxx
DB_PASSWORD=super_secret_password
STRIPE_KEY=sk_live_xxxxxxxxxxxxx
Solución de Problemas
Problemas Comunes
Colecciones No Cargan
- Verificar que
bruno.jsonexiste en raíz de colección - Verificar permisos de archivo
- Asegurar que archivos .bru usan sintaxis correcta
Variables de Entorno No Resuelven
- Verificar que el entorno está seleccionado
- Verificar spelling de nombre de variable
- Para variables
process.env, asegurar que están exportadas
Scripts No Ejecutan
- Verificar errores de sintaxis JavaScript
- Verificar que módulos Node.js están disponibles
- Revisar output de consola para mensajes de error
Optimización de Rendimiento
Colecciones Grandes
- Dividir en múltiples colecciones
- Usar organización de carpetas
- Carga selectiva en CLI
Tiempo de Respuesta
- Monitorear condiciones de red
- Verificar configuraciones de timeout
- Usar connection pooling para requests masivos
Comparación: Bruno vs Competidores
Al elegir un cliente API, vale la pena comparar Bruno contra alternativas como Insomnia REST client:
| Característica | Bruno | Postman | Insomnia | Thunder Client |
|---|---|---|---|---|
| Costo | Gratis | Freemium | Freemium | Gratis + Pro |
| Offline | Sí | Limitado | Sí | Sí |
| Almacenamiento | Archivos locales | Cloud | Híbrido | Workspace VS Code |
| Compatible Git | Excelente | Pobre | Moderado | Bueno |
| Colaboración | Basada en Git | Incorporada | Pago | Limitada |
| Curva de Aprendizaje | Baja | Media | Baja | Muy Baja |
| Extensibilidad | Scripts | Scripts + Apps | Plugins | Limitada |
Conclusión
Bruno API Client representa un cambio de paradigma en herramientas de testing de API, priorizando flujos de trabajo de desarrollador, propiedad de datos y simplicidad. Su arquitectura basada en archivos se alinea perfectamente con prácticas modernas de desarrollo centradas en Git, haciéndolo una opción ideal para equipos ya cómodos con control de versiones.
La naturaleza open-source asegura transparencia, innovación impulsada por la comunidad y libertad del vendor lock-in. Aunque puede carecer de algunas características avanzadas encontradas en herramientas establecidas como Postman, el enfoque de Bruno en funcionalidad central y experiencia del desarrollador lo hace cada vez más atractivo para equipos que buscan una alternativa liviana y enfocada en privacidad.
Ya sea que estés migrando desde Postman, comenzando de cero con testing de API, o buscando mejor integración con tu flujo de trabajo Git, Bruno ofrece una solución convincente y costo-efectiva que pone a los desarrolladores primero.
Ver También
- Comparación de Alternativas a Postman - Análisis completo de opciones disponibles
- Insomnia REST Client - Otra alternativa popular a Postman
- Thunder REST Client para VS Code - Cliente API ligero integrado en el editor
- Comparación de Herramientas API 2025 - Guía actualizada de herramientas de testing
- Domina el Testing de APIs - Fundamentos y mejores prácticas de testing