Por qué una API generada en lugar de un backend escrito a mano
En la mayoría de las aplicaciones, buena parte del código de servidor solo traduce peticiones HTTP a SQL: listar, filtrar, paginar, crear, modificar, borrar, comprobando cada vez que el usuario tiene derecho a hacerlo. Ese código es repetitivo, hay que probarlo y cada nueva columna obliga a retocarlo.
Hasura parte del esquema de la base. Una tabla seguida se convierte en un tipo GraphQL, una clave foránea en un campo anidado, y una regla de permiso escrita una vez se aplica a todas las consultas. La lógica propia de tu negocio — un pago, un envío de correo, un cálculo — se queda en tu código, al que Hasura llama por webhook. Conservas la base PostgreSQL: nada queda encerrado en un formato propietario.
Lo que aporta Hasura
- API GraphQL instantánea — consultas, mutaciones, filtros, ordenación, paginación y agregados sobre cada tabla seguida.
- Relaciones — las claves foráneas se convierten en campos anidados, consultables en una sola petición.
- Suscripciones en tiempo real — un cliente se suscribe a una consulta y recibe los cambios por WebSocket.
- Permisos por rol — reglas por fila y por columna, alimentadas por los claims de un token JWT.
- Actions y triggers — webhooks llamados por una mutación, por un cambio de datos o según un horario cron.
- Consola y endpoints REST — administración web, explorador GraphiQL y conversión de una consulta en ruta REST.
Hasura frente a otras formas de exponer PostgreSQL
Desplace la tabla
| Hasura | API escrita a mano | PostgREST | |
|---|---|---|---|
| API generada desde el esquema | Sí, GraphQL y REST | No | Sí, REST |
| Relaciones anidadas en una petición | Sí | Según el código | Sí, por embedding |
| Tiempo real | Suscripciones GraphQL | Por desarrollar | No |
| Permisos | Por rol, fila y columna, en la consola | En el código | Roles y RLS de PostgreSQL |
| Lógica de negocio | Actions y triggers en webhooks | Libre | Funciones SQL |
| Interfaz de administración | Consola web | No | No |
Requisitos previos
Un VPS Ubuntu 24.04 con 1 GB de RAM basta para empezar: en reposo, el motor Hasura y PostgreSQL ocupan juntos unos 200 MB. Prevé 2 GB en cuanto la base crezca o se multipliquen las suscripciones. Necesitas Docker con el plugin Compose y un nombre de dominio que apunte al VPS, con nginx y un certificado HTTPS: tu API la llamarán navegadores y aplicaciones móviles, debe responder en una dirección estable y cifrada.
Instalar Hasura con Docker Compose
Preparar los secretos
Crea el directorio de la aplicación y un archivo
.envcon la contraseña de la base y el admin secret, la clave maestra de la API. Solo root puede leer el archivo.mkdir -p /opt/hasura && cd /opt/hasura cat > .env <<EOF DB_PASSWORD=$(openssl rand -hex 16) ADMIN_SECRET=$(openssl rand -hex 24) EOF chmod 600 .envCrear el archivo Compose
Este
docker-compose.ymlarranca PostgreSQL en la red interna de la stack, sin puerto publicado, y después Hasura cuando la base está lista. El puerto de Hasura solo se publica en la interfaz local; la consola se sirve desde la imagen, sin llamar al CDN del editor, y la telemetría está desactivada.services: postgres: image: postgres:17.11-alpine restart: unless-stopped environment: POSTGRES_DB: hasura POSTGRES_USER: hasura POSTGRES_PASSWORD: ${DB_PASSWORD} volumes: - hasura-pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U hasura -d hasura"] interval: 10s retries: 10 hasura: image: hasura/graphql-engine:v2.51.3 restart: unless-stopped depends_on: postgres: condition: service_healthy ports: - "127.0.0.1:8103:8080" env_file: .env environment: HASURA_GRAPHQL_DATABASE_URL: postgres://hasura:${DB_PASSWORD}@postgres:5432/hasura HASURA_GRAPHQL_ADMIN_SECRET: ${ADMIN_SECRET} HASURA_GRAPHQL_ENABLE_CONSOLE: "true" HASURA_GRAPHQL_CONSOLE_ASSETS_DIR: /srv/console-assets HASURA_GRAPHQL_DEV_MODE: "false" HASURA_GRAPHQL_ENABLE_TELEMETRY: "false" volumes: hasura-pgdata: {}Arrancar la stack
En el primer arranque, Hasura crea sus tablas de metadatos en el esquema
hdb_catalogy conecta la base como fuentedefault. El endpoint/healthzrespondeOKcuando el motor está listo.docker compose up -d curl -fsS http://127.0.0.1:8103/healthz # OKPublicar en HTTPS detrás de nginx
Añade un bloque
serverpara tu dominio, con un certificado Let's Encrypt. Las cabecerasUpgradeyConnectionson imprescindibles: las suscripciones pasan por WebSocket.location / { proxy_pass http://127.0.0.1:8103; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
El admin secret nunca sale del servidor
Sin HASURA_GRAPHQL_ADMIN_SECRET, la consola y toda la API quedan abiertas a cualquiera que conozca la dirección. Con él, otorga todos los derechos: leer y escribir todas las tablas, ejecutar SQL, modificar los metadatos. Resérvalo para la consola y tus scripts de administración, y nunca lo pongas en el código de un frontend o de una aplicación móvil.
Crear una tabla y consultarla
Abre https://api.example.com/console, introduce el admin secret y, en la pestaña Data, crea una tabla todos con las columnas id (entero autoincremental), title (texto) y done (booleano). Pulsa Track: la tabla aparece al instante en el explorador de la pestaña API. Desde un script de administración, la misma consulta se envía con el admin secret:
curl -s https://api.example.com/v1/graphql \
-H "x-hasura-admin-secret: $ADMIN_SECRET" \
-H 'content-type: application/json' \
-d '{"query":"{ todos { id title done } }"}'Autenticar a tus usuarios y fijar los permisos
Tus usuarios no deben usar el admin secret: presentan un token JWT emitido por tu proveedor de identidad (Logto, Authentik, Zitadel, Auth0…). Indica a Hasura dónde encontrar las claves de verificación, y qué rol dar a las peticiones sin token, en el archivo .env:
HASURA_GRAPHQL_JWT_SECRET={"type":"RS256","jwk_url":"https://auth.example.com/oidc/jwks"}
HASURA_GRAPHQL_UNAUTHORIZED_ROLE=anonymousRelanza la stack con docker compose up -d: el servicio hasura lee este archivo mediante env_file. El token debe llevar los claims x-hasura-default-role, x-hasura-allowed-roles y x-hasura-user-id. En la pestaña Permissions de cada tabla, define entonces lo que cada rol puede leer, insertar o modificar — por ejemplo, el rol user solo ve las filas en las que user_id vale X-Hasura-User-Id.
Solución de problemas
La consola muestra «invalid x-hasura-admin-secret»: el secreto introducido no coincide con el valor del .env. Compruébalo con grep ADMIN_SECRET /opt/hasura/.env y recarga la página.
Hasura se reinicia en bucle: la base no es accesible. docker compose logs hasura muestra el error de conexión; comprueba que la contraseña de la URL HASURA_GRAPHQL_DATABASE_URL es la de PostgreSQL. Si la cambiaste después del primer arranque, PostgreSQL conservó la antigua: solo lee POSTGRES_PASSWORD al crear el volumen.
Las suscripciones se cortan: el proxy inverso no transmite la actualización a WebSocket. Añade las cabeceras Upgrade y Connection indicadas más arriba y aumenta proxy_read_timeout si tus clientes permanecen inactivos mucho tiempo.
Una tabla no aparece en la API: existe en la base pero no está seguida. Pulsa Track en la pestaña Data, o sigue todas las tablas del esquema de una vez.
Instalación en un clic desde el Marketplace de ServOrbit
El Marketplace de ServOrbit instala Hasura en tu VPS sin línea de comandos: despliega PostgreSQL y el motor Hasura, genera el admin secret y la contraseña de la base, conecta la base como fuente default y publica la API en HTTPS en un subdominio de tu dominio o en el subdominio gratuito del VPS. El admin secret aparece en tu área de cliente; solo queda abrir la consola y crear tus tablas.