Logo
Nuevos usuarios de RPC: 35% de descuento el primer mesVer oferta
OnFinality Learn
Guías de red y protocolo14 min de lectura

JSON-RPC vs gRPC vs REST: cómo elegir un protocolo de API blockchain

Análisis profundo de arquitectura de protocolos que compara JSON-RPC, gRPC y REST para API blockchain, con ejemplos ejecutables en Node.js y un método de medición reproducible.

TL;DR

JSON-RPC, gRPC y REST son tres estilos de protocolo diferentes para llamar a un nodo o indexador de blockchain. JSON-RPC es un protocolo sin estado y orientado a métodos donde cada solicitud es un objeto JSON con jsonrpc, method, params e id, y cada método se asigna a una operación concreta de la cadena, como eth_getBalance o eth_call. gRPC es un framework RPC basado en HTTP/2 y serializado con Protobuf, con definiciones de servicio tipadas y streaming, cada vez más usado por SDKs de cadenas nuevas. REST está orientado a recursos, con verbos HTTP y códigos de estado, cómodo para datos indexados de tipo CRUD, pero poco adecuado para llamadas a nodos en vivo o suscripciones. La confusión de las tres capas es que transporte, estilo de mensajería y codificación de payload son decisiones independientes, por lo que 'gRPC vs REST' no es el mismo eje que 'HTTP vs WebSocket'. Este artículo separa el comportamiento documentado del comportamiento específico de cada proveedor y te da un método reproducible para medir bytes de solicitud, bytes de respuesta y tiempo de reloj contra tu propio endpoint.

Las tres capas independientes de una llamada a API blockchain

La mayoría de los debates sobre protocolos colapsan tres decisiones independientes en una sola. La primera es el transporte: HTTP/1.1, HTTP/2, WebSocket o IPC. La segunda es el estilo de mensajería: RPC (orientado a métodos) frente a REST (orientado a recursos). La tercera es la codificación del payload: texto JSON frente a binario Protobuf. Estas decisiones son ortogonales, por lo que 'gRPC vs REST' no es el mismo eje que 'HTTP vs WebSocket'.

gRPC, por ejemplo, se define por la combinación de transporte HTTP/2, codificación Protobuf y un estilo de mensajería RPC con definiciones de servicio tipadas. REST suele ser HTTP/1.1 o HTTP/2 con codificación JSON y un estilo orientado a recursos. JSON-RPC normalmente usa transporte HTTP o WebSocket con codificación JSON y un estilo RPC. Puedes mezclarlos: JSON-RPC sobre WebSocket sigue siendo JSON-RPC, y una API REST puede devolver Protobuf.

Mantener las capas separadas evita errores de categoría. Cuando alguien dice que una cadena 'soporta gRPC', normalmente significa que existe una definición de servicio tipada y es accesible por HTTP/2. Cuando dicen que un nodo 'soporta WebSocket', se refieren a un transporte que habilita notificaciones push. Son capacidades diferentes, y puede que necesites ambas. Para una comparación a nivel de transporte específicamente de JSON-RPC, consulta JSON-RPC sobre HTTP, WebSocket e IPC.

  • Transporte: cómo se mueven los bytes (HTTP/1.1, HTTP/2, WebSocket, IPC).
  • Estilo de mensajería: cómo se nombran las operaciones (métodos RPC vs recursos REST).
  • Codificación: cómo se serializan los payloads (texto JSON vs binario Protobuf).

Qué es realmente JSON-RPC para un nodo blockchain

JSON-RPC es un protocolo sin estado y orientado a métodos. La especificación JSON-RPC 2.0 define un objeto de solicitud con cuatro miembros: jsonrpc (la cadena de versión), method (el nombre de la operación), params (un array u objeto de argumentos) e id (un identificador de correlación). El servidor devuelve un miembro result o un objeto de error estructurado con code, message y data opcional.

Para un nodo blockchain, cada método se asigna a una operación concreta de la cadena. La especificación JSON-RPC de Ethereum documenta métodos como eth_getBalance, eth_call, eth_getBlockByNumber y eth_sendRawTransaction. El nombre del método es el contrato: no hay jerarquía de URI ni semántica de verbos HTTP que interpretar. Un POST al único endpoint del nodo con un cuerpo JSON es todo el modelo de interacción.

Como JSON-RPC no tiene estado, cada solicitud lleva todo lo necesario para ejecutarla. Eso lo hace trivialmente escalable en horizontal y fácil de proxificar, pero también significa que no hay esquema en el propio protocolo. Los tipos se documentan por método, no se imponen en el formato de transmisión. Esta es la raíz tanto de su universalidad como de su verbosidad: cada cadena expone JSON-RPC, pero los clientes deben conocer la forma de cada método a partir de la documentación o de una librería cliente.

  • Sobre de solicitud: {jsonrpc, method, params, id}.
  • Sobre de respuesta: {jsonrpc, result, id} o {jsonrpc, error, id}.
  • Sin jerarquía de URI, sin semántica de verbos HTTP, sin esquema integrado.
  • Soportado universalmente en todas las cadenas; el valor por defecto de facto para acceso a nodos.

Qué es gRPC y por qué los SDKs de cadenas nuevas lo adoptan

gRPC es un framework RPC basado en HTTP/2 y serializado con Protobuf. La introducción a gRPC lo describe como el uso de HTTP/2 para el transporte, Protocol Buffers para la serialización y un lenguaje de definición de servicios para contratos tipados. Admite llamadas unarias, streaming de servidor, streaming de cliente y streaming bidireccional, y genera código de cliente y servidor a partir de la definición del servicio.

Las ventajas prácticas son contratos tipados y menor sobrecarga por mensaje. Protobuf codifica los campos como binario etiquetado, por lo que un mensaje con unos pocos campos numéricos suele ser más pequeño que el texto JSON equivalente. La generación de código hace que el cliente conozca los tipos exactos de solicitud y respuesta en tiempo de compilación, lo que reduce errores de integración. El streaming permite que una sola conexión transporte un flujo continuo de actualizaciones.

Los SDKs de cadenas nuevas exponen cada vez más API gRPC, a veces junto a JSON-RPC. La API gRPC de Sui es un ejemplo documentado de una cadena que ofrece una superficie gRPC tipada. La contrapartida es que gRPC no se puede llamar directamente desde un navegador sin un proxy como gRPC-Web, y requiere generación de código como paso de compilación. Para servicios backend e indexadores, ese coste suele merecer la pena; para un script rápido o una dApp de navegador, JSON-RPC sobre HTTP sigue siendo más sencillo.

  • Transporte: HTTP/2 con flujos multiplexados.
  • Codificación: binario Protobuf con etiquetas de campo tipadas.
  • Contrato: definición de servicio con código de cliente/servidor generado.
  • Streaming: unario, de servidor, de cliente y bidireccional.
  • Limitación en navegador: necesita gRPC-Web o un proxy para llamar desde una página.

Qué es REST y dónde encaja en blockchain

REST está orientado a recursos. Las URI identifican recursos, los verbos HTTP expresan la intención (GET, POST, PUT, DELETE) y los códigos de estado HTTP comunican los resultados. Es un excelente ajuste para datos de tipo CRUD: obtener una lista de transacciones, recuperar los metadatos de un token, consultar un indexador para saldos históricos. La interfaz uniforme hace que el almacenamiento en caché, la paginación y las URL legibles por humanos sean sencillos.

Es un mal ajuste para las llamadas con estado, cargadas de métodos y orientadas a suscripciones que expone un nodo blockchain. Las operaciones de un nodo no son recursos: eth_call es un cálculo contra un estado de bloque específico, no un GET sobre una URI. Modelarlo como REST requeriría inventar una jerarquía de recursos que no existe, y perderías el contrato de nombre de método que ya entiende todo cliente de cadena.

En la práctica, REST aparece en blockchain como una API de indexador o explorador sobre un nodo. El indexador ingiere bloques y expone recursos consultables. Eso es genuinamente útil para analítica y paneles, pero no sustituye a las llamadas a nodos en vivo. Si necesitas el estado actual de la cadena, llamas al nodo; si necesitas un agregado histórico, llamas al indexador.

  • URI orientadas a recursos con verbos HTTP y códigos de estado.
  • Fuerte para datos indexados, de tipo CRUD y cacheables.
  • Débil para estado de nodo en vivo, llamadas cargadas de métodos y suscripciones.
  • Habitualmente implementado como capa de indexador, no como interfaz de nodo.

Tabla comparativa de los ejes del protocolo

La siguiente tabla compara los tres estilos en los ejes que importan al elegir una API blockchain. Trátala como comportamiento documentado y características generales, no como un benchmark. Las implementaciones específicas de cada proveedor varían, y deberías verificar la superficie exacta que expone tu proveedor.

La fila 'uso típico en blockchain' es la más relevante para decidir. JSON-RPC es el valor por defecto para leer y escribir el estado de la cadena. gRPC es común en servicios backend y SDKs que quieren contratos tipados y streaming. REST es común en indexadores, exploradores y endpoints de analítica.

  • Forma de solicitud — JSON-RPC: un único POST con método y params. gRPC: mensaje de solicitud tipado. REST: URI más verbo HTTP.
  • Codificación — JSON-RPC: texto JSON. gRPC: binario Protobuf. REST: normalmente texto JSON.
  • Streaming — JSON-RPC: no en el protocolo base; las suscripciones WebSocket son una característica de transporte aparte. gRPC: unario y streaming nativos. REST: no nativo; polling o SSE.
  • Herramientas — JSON-RPC: curl, cualquier cliente HTTP, sin generación de código. gRPC: protoc y stubs generados. REST: curl, cualquier cliente HTTP, OpenAPI opcional.
  • Amigabilidad con el navegador — JSON-RPC: alta sobre HTTP. gRPC: baja sin gRPC-Web o un proxy. REST: alta.
  • Uso típico en blockchain — JSON-RPC: lecturas y escrituras de nodo. gRPC: SDKs tipados y streaming backend. REST: indexadores, exploradores, analítica.

Ejemplo ejecutable en Node.js: el mismo saldo de tres formas

El ejemplo siguiente realiza la misma operación lógica —obtener un saldo— de tres formas. La primera es un POST JSON-RPC a un endpoint de nodo. La segunda es un GET de estilo REST contra un indexador. La tercera es una llamada gRPC conceptual usando un cliente tipado; se muestra como stub porque la definición del servicio y el nombre del paquete son específicos de cada cadena y deben provenir del SDK de la cadena.

El script mide bytes de solicitud, bytes de respuesta y tiempo de reloj para cada llamada. Usa solo módulos integrados de Node.js para las rutas HTTP, por lo que puedes ejecutarlo sin instalar dependencias. Sustituye los endpoints y direcciones de ejemplo por los tuyos. La rama gRPC está comentada intencionadamente para evitar inventar una definición de servicio.

Ejecútalo con node balance-compare.js. La salida es una pequeña tabla que puedes pegar en tu propia hoja de resultados. Como los endpoints son distintos, la comparación es ilustrativa de forma y sobrecarga, no un benchmark controlado. Para una comparación controlada, apunta los tres al mismo proveedor y a la misma altura de bloque.

// balance-compare.js — Node.js 18+ (built-in fetch)
const NODE_RPC = process.env.NODE_RPC || 'https://your-node-endpoint';
const INDEXER_REST = process.env.INDEXER_REST || 'https://your-indexer-endpoint';
const ADDRESS = process.env.ADDRESS || '0x0000000000000000000000000000000000000000';

function bytesOf(str) { return Buffer.byteLength(str, 'utf8'); }

async function timed(label, fn) {
  const start = process.hrtime.bigint();
  const { reqBytes, resBytes, note } = await fn();
  const end = process.hrtime.bigint();
  const ms = Number(end - start) / 1e6;
  return { label, reqBytes, resBytes, ms: ms.toFixed(2), note };
}

async function jsonRpcBalance() {
  const body = JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'eth_getBalance',
    params: [ADDRESS, 'latest']
  });
  const res = await fetch(NODE_RPC, {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body
  });
  const text = await res.text();
  return { reqBytes: bytesOf(body), resBytes: bytesOf(text), note: 'JSON-RPC POST' };
}

async function restBalance() {
  const url = `${INDEXER_REST}/v1/addresses/${ADDRESS}/balance`;
  const res = await fetch(url, { method: 'GET' });
  const text = await res.text();
  return { reqBytes: bytesOf(url), resBytes: bytesOf(text), note: 'REST GET' };
}

// Conceptual gRPC branch: requires a chain-specific .proto and generated client.
// async function grpcBalance() {
//   const grpc = require('@grpc/grpc-js');
//   const protoLoader = require('@grpc/proto-loader');
//   const def = protoLoader.loadSync('chain.proto');
//   const pkg = grpc.loadPackageDefinition(def);
//   const client = new pkg.chain.QueryService(GRPC_ENDPOINT, grpc.credentials.createInsecure());
//   const req = { address: ADDRESS };
//   const reqBytes = Buffer.from(JSON.stringify(req)).length; // Protobuf size differs
//   const res = await new Promise((resolve, reject) =>
//     client.getBalance(req, (err, r) => err ? reject(err) : resolve(r))
//   );
//   return { reqBytes, resBytes: Buffer.from(JSON.stringify(res)).length, note: 'gRPC unary' };
// }

(async () => {
  const rows = [];
  rows.push(await timed('JSON-RPC', jsonRpcBalance));
  rows.push(await timed('REST', restBalance));
  console.table(rows);
})();

Tabla de resultados reproducible para tu propio endpoint

La única forma honesta de comparar protocolos para tu carga de trabajo es medir contra tu propio endpoint. La tabla siguiente es una plantilla. Rellénala con la salida del script anterior, o con tu propia instrumentación. No trates ningún número publicado como universal: la latencia y el tamaño del payload dependen de la cadena, el método, el proveedor y la ruta de red.

Ejecuta cada operación al menos 30 veces y registra la mediana y el percentil 95, no solo una muestra. Anota la altura de bloque o el slot en el momento de la medición, porque el estado cambia entre ejecuciones. Si comparas proveedores, mantén constantes el método y la altura de bloque. Para un marco de evaluación más amplio, consulta Evaluación de soluciones de API JSON-RPC blockchain.

La columna 'beneficio de esquema/tipado observado' es cualitativa. Registra si el cliente detectó un error de tipo en tiempo de compilación, si necesitaste consultar la documentación para construir la solicitud y si la respuesta requirió análisis manual. Ahí es donde se nota la ventaja de la generación de código de gRPC, y no aparece en un recuento de bytes.

  • Operación — la acción lógica, p. ej. obtener saldo, obtener bloque, enviar transacción.
  • Protocolo — JSON-RPC, gRPC o REST.
  • Bytes de solicitud — tamaño serializado de la solicitud en la red.
  • Bytes de respuesta — tamaño serializado de la respuesta en la red.
  • Tiempo de reloj — mediana y p95 sobre al menos 30 ejecuciones.
  • Beneficio de esquema/tipado observado — seguridad de tipos en compilación, consulta de documentación, análisis manual.
  • Altura de bloque o slot — registrada en el momento de la medición para mantener las ejecuciones comparables.

Limitaciones y compensaciones de cada estilo de protocolo

JSON-RPC carece de esquema y es más verboso que las alternativas binarias, pero está soportado universalmente por todas las cadenas. Esa universalidad es un activo de ingeniería real: un patrón de cliente funciona en Ethereum, Polkadot y la mayoría de las demás redes. El coste es que a menudo necesitas múltiples round-trips para componer una vista, y debes confiar en la documentación por método para los tipos. El batching puede reducir los round-trips; consulta Buenas prácticas de batching JSON-RPC.

gRPC es eficiente y tipado, pero necesita generación de código y no se puede llamar desde un navegador sin un proxy. El paso de compilación es un coste real en CI, y los stubs generados deben regenerarse cuando cambia la definición del servicio. Para servicios backend que valoran la seguridad de tipos y el streaming, ese coste suele estar justificado. Para un script puntual, es fricción.

REST es cómodo para indexadores pero no para llamadas a nodos en vivo o suscripciones. Brilla cuando los datos ya están agregados y son cacheables. No sustituye a una suscripción WebSocket cuando necesitas notificaciones push: ninguno de estos tres estilos, en su forma base, entrega eventos iniciados por el servidor. Si necesitas reaccionar a nuevos bloques o logs en tiempo real, necesitas un transporte de suscripción, que es una decisión aparte del estilo de mensajería.

  • JSON-RPC: sin esquema, más verboso, pero universal entre cadenas.
  • gRPC: eficiente y tipado, pero necesita generación de código y un proxy para navegador.
  • REST: excelente para indexadores, pobre para llamadas a nodos en vivo y suscripciones.
  • Ninguno de los tres sustituye a las suscripciones WebSocket para notificaciones push.

Solución de problemas comunes al elegir protocolo

Un fallo frecuente es llamar a un endpoint REST esperando estado de nodo en vivo. Los indexadores van por detrás de la cabeza de la cadena por diseño, por lo que un saldo obtenido de un indexador puede estar desactualizado. Si necesitas el estado actual, llama directamente al método JSON-RPC del nodo. Si necesitas un agregado histórico, llama al indexador. Mezclar ambos sin entender el retraso produce resultados confusos.

Otro fallo es intentar una llamada gRPC desde un navegador. gRPC estándar requiere trailers HTTP/2 que los navegadores no exponen a JavaScript, por lo que necesitas gRPC-Web o un proxy. Si tu dApp debe llamar directamente a un servicio tipado, presupuesta ese proxy. De lo contrario, usa JSON-RPC sobre HTTP, que funciona desde cualquier llamada fetch del navegador.

Un tercer fallo es asumir que JSON-RPC tiene esquema y enviar params malformados. El protocolo valida el sobre, no los argumentos del método. Un tipo de parámetro incorrecto puede devolver un error estructurado o un resultado que no es el esperado. Valida siempre contra la firma documentada del método y usa una librería cliente cuando exista. Para llamadas de estilo simulación, consulta eth_call y simulación con state override.

Por último, los problemas de latencia a menudo se atribuyen erróneamente al protocolo. Si tus llamadas son lentas, mide antes de cambiar de protocolo. El cuello de botella suele ser la ruta de red o la carga del proveedor, no JSON frente a Protobuf. Consulta Reducir la latencia de RPC para un enfoque basado en medir primero.

  • Datos de indexador obsoletos confundidos con estado de nodo en vivo.
  • Llamadas gRPC desde navegador que fallan sin gRPC-Web o un proxy.
  • Params JSON-RPC malformados que pasan la validación del sobre pero fallan semánticamente.
  • Latencia atribuida al protocolo cuando la causa es la red o la carga del proveedor.

Elegir un protocolo para tu integración blockchain

Empieza por la operación, no por el protocolo. Si estás leyendo o escribiendo el estado de la cadena, JSON-RPC es el valor por defecto y la opción más segura porque todas las cadenas lo soportan. Si estás construyendo un servicio backend que se beneficia de contratos tipados y streaming, evalúa la superficie gRPC de la cadena. Si estás consultando datos históricos agregados, usa la API REST del indexador.

Para la mayoría de los equipos, la respuesta es una combinación. Usa JSON-RPC para llamadas a nodos en vivo, una suscripción WebSocket para notificaciones push, gRPC para servicios backend tipados donde la cadena lo ofrezca, y REST para analítica. Los protocolos no son tanto competidores como capas, y el modelo de tres capas de la primera sección es la herramienta que mantiene el orden.

Cuando evalúes proveedores, comprueba qué superficies exponen y cómo las documentan. Un proveedor que ofrece JSON-RPC, WebSocket y gRPC bajo una misma cuenta reduce la fricción de integración. Puedes revisar las superficies disponibles en la página de servicio de API y comparar modelos de coste en precios de RPC. Para endpoints específicos de red, consulta Ethereum.

  • Lecturas y escrituras de nodo en vivo: JSON-RPC sobre HTTP.
  • Notificaciones push: suscripción WebSocket.
  • Servicios backend tipados: gRPC donde la cadena lo ofrezca.
  • Agregados históricos: API REST del indexador.

Próximos pasos y lecturas adicionales

El siguiente paso más útil es ejecutar el script de medición contra tus propios endpoints y rellenar la tabla de resultados. Eso te da una base defendible para una decisión de protocolo en lugar de una suposición. Registra la altura de bloque, ejecuta suficientes muestras y anota el beneficio cualitativo de tipado junto a los recuentos de bytes.

A partir de ahí, profundiza en la capa de transporte con JSON-RPC sobre HTTP, WebSocket e IPC, y reduce round-trips con Buenas prácticas de batching JSON-RPC. Si estás seleccionando un proveedor, la guía Evaluación de soluciones de API JSON-RPC blockchain cubre los criterios que importan más allá del estilo de protocolo.

Para un índice más amplio de material relacionado, empieza en el centro de aprendizaje de OnFinality. El objetivo no es elegir un ganador entre JSON-RPC, gRPC y REST, sino hacer coincidir cada capa de tu arquitectura con el estilo de protocolo que le corresponde.

  • Ejecuta el script de medición y rellena la tabla de resultados.
  • Revisa las opciones de transporte para JSON-RPC.
  • Aplica batching para reducir round-trips.
  • Evalúa proveedores por las superficies que exponen, no solo por el precio.

Nunca te preocupes por la infraestructura nuevamente

OnFinality elimina la carga pesada de DevOps para que puedas construir de forma más inteligente y rápida.

Comenzar