7. Paginación
El servicio siempre pagina. Una colección sin $top no devuelve la tabla completa: devuelve una página y un @odata.nextLink.
{
"value": [ ... 1000 filas ... ],
"@odata.nextLink": "https://TU-HOST/synergy-server/jwt-odata-key/o_customers?$skiptoken=czoxMDAw"
}
El patrón correcto para recorrer todo
url = base + "/o_customers"
while url:
r = get(url)
procesar(r["value"])
url = r.get("@odata.nextLink") # se usa tal cual, es opaco
if not r["value"]: # corte defensivo, ver abajo
break
El nextLink puede apuntar a una página vacía. Cuando el total es múltiplo exacto del tamaño de página, el servidor no sabe que no hay más y manda el link igual. No es un error: cortá cuando value venga vacío, no solo cuando falte el nextLink.
| Tema | Comportamiento |
|---|---|
| Tamaño de página | 1000 filas por defecto. El administrador puede bajarlo por entidad. |
$top | Si pedís más que el tope, se te da el tope y un nextLink con lo que falta. $top=0 devuelve {"value":[]}. |
Prefer: odata.maxpagesize=N | Solo puede reducir la página. La respuesta trae Preference-Applied con el tamaño realmente aplicado. |
$skiptoken | Opaco. No lo construyas a mano ni asumas su contenido. |
$skip + $skiptoken | No se combinan: si viene $skiptoken, el $skip se descarta. |
@odata.count | Con $count=true. Es el total que coincide con el filtro, independiente de $top, $skip y del tamaño de página. |
Colecciones expandidas
Un $expand de una colección sin $top anidado trae como máximo 1000 hijos por padre. Cuando se corta, el padre recibe un nextLink propio apuntando a la colección navegable:
"Comprobantes@odata.nextLink": "https://TU-HOST/synergy-server/jwt-odata-key/o_customers('C0001')/Comprobantes?$skip=1000"
Ese aviso solo llega en el primer nivel. Una colección expandida dentro de otro $expand (por ejemplo $expand=Localidad($expand=Clientes)) se corta en 1000 sin emitir nextLink. Si esperás más de mil hijos en un nivel anidado, traelos con una consulta aparte sobre la entidad hija en vez de expandirlos.