Tema
Probar APIs con Bruno
Bruno es un cliente de API parecido a Postman, pero guarda las colecciones como archivos de texto en tu disco — lo que significa que puedes versionarlas con Git.
Descárgalo en usebruno.com.
Crear la colección
- Collection → Create Collection, nómbrala
ReservaLab. - Guárdala dentro de tu repositorio (
studentNN-qa/bruno/) para poder subirla.
Definir el entorno
Un entorno guarda los valores que se repiten. Así no escribes la URL veinte veces ni pegas el token a mano.
Environments → Configure → Create, nómbralo laboratorio:
| Variable | Valor |
|---|---|
baseUrl | https://api.theproject.ec |
email | studentNN@theproject.ec |
password | tu contraseña |
token | (vacío: se rellena solo) |
Las peticiones
1. Estado del servicio
GET {{baseUrl}}/healthRespuesta esperada:
json
{ "estado": "ok", "base_de_datos": "ok", "bugs_activos": true, "fecha": "..." }2. Catálogo de servicios
GET {{baseUrl}}/servicesApunta el id de un servicio: lo vas a necesitar para reservar.
3. Iniciar sesión
POST {{baseUrl}}/auth/loginCuerpo (pestaña Body → JSON):
json
{
"email": "{{email}}",
"password": "{{password}}"
}En la pestaña Script → Post Response, pega esto para que el token se guarde solo:
js
if (res.status === 200) {
bru.setEnvVar("token", res.body.token);
}TIP
Este truco ahorra muchísimo tiempo: cada vez que ejecutes el login, el resto de las peticiones quedan autenticadas automáticamente.
4. Tus citas
GET {{baseUrl}}/appointmentsEn Headers:
Authorization: Bearer {{token}}5. Reservar una cita
POST {{baseUrl}}/appointmentsCon la misma cabecera de autorización y este cuerpo:
json
{
"service_id": 1,
"fecha": "2026-12-15T10:00:00Z",
"notas": "Prueba desde Bruno"
}Cambia service_id por uno real y usa una fecha futura.
6. Cancelar una cita
POST {{baseUrl}}/appointments/123/cancelSin cuerpo. Cambia 123 por el id de una de tus citas.
Un detalle que da problemas
Esta petición no lleva cuerpo. Si tu cliente anuncia Content-Type: application/json sin enviar nada, el servidor responde 400 ("Body cannot be empty"). En Bruno, deja el Body en None.
No es un capricho: este mismo error se colará en tu código si no lo tienes presente.
Aserciones automáticas
Bruno puede comprobar la respuesta por ti. En la pestaña Assert:
| Expr | Operator | Value |
|---|---|---|
res.status | eq | 200 |
res.body.estado | eq | ok |
O en la pestaña Tests, con código:
js
test("responde 200", function () {
expect(res.getStatus()).to.equal(200);
});
test("hay servicios en el catalogo", function () {
expect(res.getBody().total).to.be.above(0);
});Versionar la colección
Como Bruno guarda archivos .bru de texto plano:
bash
git add bruno/
git commit -m "test: coleccion de api de reservalab"
git pushEso es parte del entregable del módulo 2.
Si prefieres la línea de comandos
Todo lo anterior con curl:
bash
API=https://api.theproject.ec
# Login y guardar el token
TOKEN=$(curl -s -X POST $API/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"studentNN@theproject.ec","password":"tu-contraseña"}' \
| python -c 'import sys,json; print(json.load(sys.stdin)["token"])')
# Tus citas
curl -s $API/appointments -H "Authorization: Bearer $TOKEN"
# Reservar
curl -s -X POST $API/appointments \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"service_id":1,"fecha":"2026-12-15T10:00:00Z"}'
# Cancelar (¡sin -d y sin Content-Type!)
curl -s -X POST $API/appointments/123/cancel \
-H "Authorization: Bearer $TOKEN"Añade -i para ver las cabeceras y el código de estado en la respuesta.