Consultas
Vincent Depassier · 29 de agosto de 2026
PraxQL — Consultas
Un cuerpo query lee datos de una tabla principal, con filtrado, orden, paginación y relaciones anidadas opcionales.
Consulta mínima
{
"refs": {
"Clientes": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
},
"query": {
"from": "Clientes"
}
}Devuelve todas las columnas permitidas de Clientes, hasta el límite por defecto.
from (obligatorio)
El alias de la tabla principal. Tiene que existir como clave en refs.
select (opcional)
Un array de nombres de columna. Omitilo para traer todas las permitidas.
"select": ["Nombre", "Email", "Telefono"]Los objetos de relación (joins) se mezclan libremente con los nombres:
"select": [
"Nombre",
"Email",
{ "table": "Pedidos", "select": ["Total", "Fecha"] }
]Está todo en PraxQL — Relaciones.
Cuando dos tablas unidas comparten el nombre de una columna, prefijala con el alias:
"select": ["Clientes.Nombre", "Pedidos.Nombre"]where (opcional)
Un array de condiciones. Las del mismo nivel se combinan con AND automáticamente.
"where": [
{ "field": "Estado", "op": "eq", "value": "Activo" },
{ "field": "Region", "op": "eq", "value": "EU" }
]Produce WHERE Estado = 'Activo' AND Region = 'EU'.
Campo | Tipo | Descripción |
| string | Nombre de columna |
| string | Operador — ver PraxQL — Operadores |
| cualquiera | El valor a comparar: string, número, booleano, null o array |
Para OR usá la clave or; para agrupar AND explícitamente, and. Ambos están en PraxQL — Operadores.
orderBy (opcional)
Un array de especificaciones de orden, aplicadas en secuencia — el primer elemento es el orden principal.
"orderBy": [
{ "field": "Apellido", "dir": "asc" },
{ "field": "FechaCreacion", "dir": "desc" }
]La columna necesita CanSort = true en el scope de columna de la credencial. Una credencial sin scopes de columna definidos puede ordenar por cualquiera.
limit y offset (opcionales)
"limit": 25,
"offset": 50Devuelve las filas 51–75, la tercera página de 25.
| Valor |
Por defecto, si omitís | 50 |
Tope por defecto en un scope de tabla recién creado | 200 ( |
Máximo absoluto, que nada sube | 1.000 |
El techo efectivo es el menor entre el tope del scope y el máximo absoluto — o sea que de fábrica son 200, no 1.000, y alguien tiene que ampliar el scope antes de que sea posible una página más grande.
Pedir más que el techo no falla: te devuelve el techo, en silencio. Leé siempre meta.limit en la respuesta en vez de asumir que recibiste lo que pediste.
Paginación
Página 1:
{
"refs": { "Pedidos": "..." },
"query": {
"from": "Pedidos",
"orderBy": [{ "field": "FechaCreacion", "dir": "desc" }],
"limit": 50,
"offset": 0
},
"includeTotalCount": true
}La respuesta trae meta.total, que te dice cuántas páginas hay.
Página 2 es el mismo cuerpo con "offset": 50. Pedí includeTotalCount solo en la primera — cada página siguiente pagaría un conteo extra que devuelve un número que ya tenés.
Mandá siempre un orderBy al paginar. Sin él, nada garantiza el orden de las filas entre requests, así que una fila puede aparecer en dos páginas o en ninguna.
groupBy y having
Para totales, promedios y conteos por grupo, usá groupBy con funciones de agregación en select, y opcionalmente having para filtrar los grupos. Está en PraxQL — Agregaciones.
Ejemplo completo
{
"refs": {
"Clientes": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
},
"query": {
"from": "Clientes",
"select": ["Nombre", "Email", "Estado", "Region"],
"where": [
{ "field": "Estado", "op": "eq", "value": "Activo" },
{
"or": [
{ "field": "Region", "op": "eq", "value": "EU" },
{ "field": "Region", "op": "eq", "value": "LATAM" }
]
}
],
"orderBy": [{ "field": "Nombre", "dir": "asc" }],
"limit": 50,
"offset": 0
}
}Clientes activos en EU o LATAM, ordenados por nombre, de a cincuenta.