Logo
Nuevos usuarios de RPC: 35% de descuento el primer mesVer oferta
OnFinality Learn
Integración y Desarrollo11 min de lectura

Arquitectura de API Web3: Cómo las dApps se comunican con las blockchains y cómo verificarlo

Una guía práctica sobre las capas de API Web3, desde el transporte JSON-RPC hasta las API de datos indexados, con comprobaciones ejecutables y un método de medición que puedes reproducir.

TL;DR

Una API Web3 es el contrato entre tu aplicación y una red blockchain: define cómo lees el estado, envías transacciones y te suscribes a eventos. La mayoría de las API Web3 se basan en JSON-RPC, con API indexadas estilo REST o GraphQL añadidas para mayor comodidad en las consultas. Este artículo explica las capas, muestra llamadas ejecutables contra un RPC_URL de marcador de posición y ofrece un procedimiento reproducible para medir latencia, consistencia y comportamiento ante fallos. Separa el comportamiento documentado del protocolo de las recomendaciones del proveedor y de las cifras que debes medir tú mismo.

Qué es realmente una API Web3

Una API Web3 es un conjunto de estándares y endpoints que permiten a una aplicación leer el estado de la blockchain, difundir transacciones firmadas y observar eventos sin ejecutar su propio nodo. El término abarca varias capas distintas que a menudo se comercializan juntas: la interfaz JSON-RPC sin procesar que exponen los nodos, las bibliotecas cliente como web3.js o ethers que envuelven esa interfaz, y las API mejoradas o indexadas que precalculan datos como saldos de tokens, metadatos de NFT o historiales de transacciones.

El modelo mental importante es que solo la capa de nodo es autoritativa. Las API mejoradas son vistas derivadas construidas mediante indexación y almacenamiento en caché de datos del nodo, por lo que son convenientes pero pueden retrasarse o divergir durante reorganizaciones. Cuando la corrección importa, verifica contra un RPC de nodo. Cuando la velocidad de desarrollo importa, una API indexada puede eliminar muchos viajes de ida y vuelta.

Esta guía se centra en la mecánica y en cómo verificar cualquier API Web3 que adoptes. Para una elección concreta de endpoint o proveedor, las respuestas del RPC Assistant complementario son el lugar adecuado para empezar; esta página prioriza la metodología.

  • JSON-RPC de nodo: lecturas autoritativas, envío de transacciones, suscripciones.
  • Bibliotecas cliente: envoltorios tipados, firma, codificación ABI.
  • API indexadas/mejoradas: saldos, historiales y metadatos precalculados.
  • Cada capa tiene características diferentes de consistencia y latencia.

Requisitos previos y suposiciones

Necesitas Node.js 18+ o Python 3.10+, curl y un endpoint RPC para una red que controles o puedas consultar. Todos los ejemplos usan el marcador de posición RPC_URL; reemplázalo con un endpoint de tu proveedor o tu propio nodo. Nunca confirmes claves reales. Para operaciones de escritura, usa una PRIVATE_KEY desechable en una testnet.

Los ejemplos asumen una cadena compatible con EVM porque los nombres de métodos JSON-RPC están estandarizados allí. Las redes no EVM exponen métodos análogos con nombres diferentes, así que trata los nombres de métodos como ejemplos del patrón en lugar de constantes universales.

El modelo mental por capas: transporte, protocolo, semántica

Separa tres preocupaciones al depurar una API Web3. El transporte es cómo se mueven los bytes: HTTP POST, WebSocket o IPC. El protocolo es la forma del mensaje: sobres JSON-RPC 2.0 con method, params, id y result o error. La semántica es lo que significa el método: eth_getBalance devuelve una cantidad hexadecimal en wei en una etiqueta de bloque dada, mientras que eth_getLogs devuelve registros de eventos filtrados por dirección y temas.

La mayoría de los errores de integración son semánticos, no de transporte. Una respuesta 200 OK aún puede contener un objeto de error JSON-RPC. Un saldo puede ser correcto en latest pero estar desactualizado en un bloque específico. Una consulta de logs puede devolver silenciosamente un array vacío porque el filtro de temas estaba mal formado. Inspecciona siempre el campo error antes de confiar en el resultado.

curl -s -X POST "$RPC_URL" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'

Ruta de lectura ejecutable: saldo, bloque y recibo

La ruta de lectura es el lugar más seguro para validar una nueva API Web3. Comienza con eth_blockNumber para confirmar la conectividad, luego eth_getBalance en un bloque fijado, y después obtén ese bloque para confirmar que el número es consistente. Fijar la etiqueta de bloque hace que los resultados sean reproducibles; latest es conveniente pero no determinista.

El ejemplo de JavaScript a continuación usa fetch, por lo que no tiene dependencias. Comprueba explícitamente el campo de error JSON-RPC, que es la omisión más común en el código de inicio rápido.

const RPC_URL = process.env.RPC_URL;
const ADDRESS = "0x0000000000000000000000000000000000000000";

async function rpc(method, params) {
  const res = await fetch(RPC_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params })
  });
  const body = await res.json();
  if (body.error) throw new Error(`${method}: ${body.error.message}`);
  return body.result;
}

const blockHex = await rpc("eth_blockNumber", []);
const block = await rpc("eth_getBlockByNumber", [blockHex, false]);
const balance = await rpc("eth_getBalance", [ADDRESS, blockHex]);
console.log({ blockHex, blockHash: block.hash, balanceWei: BigInt(balance) });

Ruta de escritura ejecutable: simula antes de enviar

Las escrituras son donde las API Web3 fallan de forma más costosa. La secuencia segura es eth_estimateGas, luego eth_call para simular, y después eth_sendRawTransaction con una carga firmada localmente. Enviar una transacción sin firmar a través de una cuenta gestionada por el proveedor es un modelo de confianza diferente y debe ser una elección deliberada, no la opción por defecto.

El ejemplo de Python usa eth_account para firmar y requests para el transporte. Lee el nonce y el chain ID del nodo, estima el gas, firma localmente y difunde. Trata PRIVATE_KEY como un secreto solo para testnet.

import os, requests
from eth_account import Account

RPC_URL = os.environ["RPC_URL"]
KEY = os.environ["PRIVATE_KEY"]

def rpc(method, params):
    r = requests.post(RPC_URL, json={"jsonrpc":"2.0","id":1,"method":method,"params":params}, timeout=10)
    body = r.json()
    if "error" in body:
        raise RuntimeError(body["error"])
    return body["result"]

acct = Account.from_key(KEY)
tx = {
    "to": acct.address,
    "value": 0,
    "nonce": int(rpc("eth_getTransactionCount", [acct.address, "pending"]), 16),
    "chainId": int(rpc("eth_chainId", []), 16),
    "gas": int(rpc("eth_estimateGas", [{"from": acct.address, "to": acct.address, "value": "0x0"}]), 16),
    "maxFeePerGas": int(rpc("eth_gasPrice", []), 16),
    "maxPriorityFeePerGas": 1_000_000_000,
}
signed = acct.sign_transaction(tx)
print(rpc("eth_sendRawTransaction", [signed.raw_transaction.hex()]))

Medir latencia y consistencia sin inventar cifras

No confíes en las cifras de latencia de marketing, incluidas las que leas aquí. Mide tu propia ruta. Ejecuta al menos 200 llamadas secuenciales a eth_blockNumber desde la misma región que tus usuarios, registra el tiempo de reloj de pared por llamada y reporta p50, p95 y p99. Luego repite con eth_getBalance en un bloque fijado para medir una lectura más pesada. Conserva el script y las muestras sin procesar para que los resultados sean reproducibles.

La consistencia es un eje separado. Consulta el mismo hash de bloque a través de dos endpoints o dos ejecuciones y compara el state root y el hash de bloque devueltos. Una discrepancia en la misma altura indica retraso, una reorganización o un backend con balanceo de carga que sirve nodos diferentes. Registra el momento de la observación junto con cada muestra.

Rellena una tabla de resultados como la de abajo con tus propias mediciones. La estructura de columnas es el entregable; los valores deben provenir de tu ejecución.

  • Método bajo prueba y etiqueta de bloque (latest vs fijada).
  • Número de muestras, región y versión del cliente.
  • Latencia p50 / p95 / p99 en milisegundos.
  • Tasa de errores por código de error JSON-RPC.
  • Comprobación de consistencia: coincidencia de hash de bloque y state root en la misma altura.

Plantilla de tabla de resultados para tu propia ejecución

MétodoEtiqueta de bloqueMuestrasp50 (ms)p95 (ms)p99 (ms)Tasa de errorCoincidencia de hash
eth_blockNumberlatest200medirmedirmedirmedirn/a
eth_getBalancefijada200medirmedirmedirmedirn/a
eth_getBlockByNumberlatest200medirmedirmedirmedircomparar
Publica el script, la región y la marca de tiempo junto con la tabla. Una cifra de latencia sin esos tres elementos de contexto no es reproducible y debe tratarse como anécdota.

Solución de problemas comunes de API Web3

La mayoría de los fallos entran en un pequeño conjunto de patrones. HTTP 429 significa que superaste un límite de tasa; retrocede con jitter en lugar de reintentar inmediatamente. El error JSON-RPC -32000 a menudo indica fondos insuficientes, conflictos de nonce o reversiones de ejecución, así que lee los campos message y data. Un resultado null de eth_getTransactionReceipt generalmente significa que la transacción aún está pendiente, no que falló.

Los arrays vacíos silenciosos de eth_getLogs con frecuencia se deben a una posición de tema inválida o a un rango de bloques que excede el límite del proveedor. Divide los rangos y valida la longitud del tema. Si una suscripción se cae, reconéctate con retroceso exponencial y vuelve a obtener los bloques perdidos por número en lugar de asumir que el flujo está completo.

Para un diagnóstico más profundo específico de endpoints, consulta la guía del RPC Assistant sobre <a href="/en/learn/rpc-endpoints-guide">fundamentos de endpoints RPC</a> y <a href="/en/learn/multi-chain-rpc-endpoints-guide">patrones de endpoints multicadena</a>.

  • 429: aplica retroceso exponencial con jitter.
  • -32000: inspecciona message y data, verifica nonce y saldo.
  • recibo null: sondea hasta que se mine o se agote el tiempo, no lo trates como fallo.
  • logs vacíos: valida los temas y divide los rangos de bloques.
  • WebSocket caído: reconéctate y rellena por número de bloque.

Limitaciones y compensaciones entre capas de API

El RPC de nodo sin procesar te da autoridad y control, pero traslada la indexación, el almacenamiento en caché y los reintentos a tu aplicación. Las API mejoradas reducen el código pero introducen una frontera de confianza en datos derivados y esquemas específicos del proveedor que complican la migración. Las bibliotecas cliente mejoran la ergonomía pero pueden ocultar el sobre de error subyacente, así que registra las respuestas sin procesar durante la integración.

El autoalojamiento elimina la dependencia de terceros pero añade coste operativo: tiempo de sincronización, crecimiento de disco, actualizaciones y monitorización. Los endpoints gestionados cambian control por elasticidad. Ninguno es universalmente mejor; la elección correcta depende de si tu cuello de botella es la corrección, la latencia, el coste o el tiempo del equipo. Revisa las <a href="/en/dedicated-node">opciones de nodo dedicado</a> y las <a href="/en/pricing/rpc">estructuras de precios de RPC</a> frente a tu perfil de solicitudes medido en lugar de las cuotas anunciadas.

Reforzar tu integración antes del lanzamiento

Envuelve cada llamada en un timeout, valida el campo de error JSON-RPC y registra el método, los params, la etiqueta de bloque y el tiempo de respuesta. Fija las etiquetas de bloque para cualquier lectura que alimente un cálculo financiero. Añade un endpoint de respaldo y un cortacircuitos para que la caída de un solo proveedor degrade el servicio con elegancia en lugar de fallar toda la dApp.

Prueba primero contra una testnet, luego repite las mismas llamadas contra mainnet con credenciales de solo lectura. Confirma que tu lógica de reintento no duplica transacciones: la idempotencia para escrituras proviene de la gestión de nonces, no de reintentar a ciegas.

  • Timeouts y comprobaciones explícitas del campo de error en cada llamada.
  • Etiquetas de bloque fijadas para lecturas deterministas.
  • Endpoint de respaldo más cortacircuitos.
  • Reintento consciente del nonce para escrituras.
  • Logs estructurados con método, params y latencia.

Próximos pasos: de la verificación a la producción

Una vez que tu tabla de medición sea estable, elige endpoints haciendo coincidir el p95 medido y la tasa de error con tu SLA, no con los promedios anunciados. Explora las cadenas compatibles en la <a href="/en/networks">página de redes</a>, compara el acceso gestionado en la <a href="/en/api-service">página del servicio API</a> y mantén los scripts de verificación en CI para que las regresiones aparezcan antes de que las vean los usuarios.

Para recomendaciones concretas de proveedores y endpoints, consulta las entradas del RPC Assistant como <a href="/en/learn/best-rpc-provider-for-web3-projects">mejor proveedor RPC para proyectos Web3</a> y <a href="/en/learn/best-ethereum-rpc-api">mejor API RPC de Ethereum</a>. Mantén esta página como la referencia metodológica que te indica cómo validar lo que elijas.

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