Resumen

JSON-RPC es un protocolo de llamada a procedimiento remoto (RPC) ligero y sin estado. Básicamente, esta especificación define diversas estructuras de datos y las reglas que rigen su procesamiento. Es agnóstico en cuanto al transporte, puesto que los conceptos pueden usarse dentro del mismo proceso, a través de conectores, a través de http o en diversos entornos de paso de mensajes. Usa JSON (RFC 4627) como formato de datos.

Está diseñado para ser sencillo.

Convenciones

Las palabras clave "DEBE", "NO DEBE", "REQUERIDO", "DEBERÁ", "NO DEBERÁ", "DEBERÍA", "NO DEBE", "RECOMENDADO", "PUEDE", y "OPCIONAL" en este documento se interpretan como se describe en el​​​​​​ RFC 2119.

Dado que JSON-RPC emplea JSON, tiene el mismo tipo de sistema (véase http://www.json.orgRFC 4627). JSON puede representar cuatro tipos primitivos (cadenas, números, booleanos y nulos) y dos tipos estructurados (objetos y matrices). El término "primitivo" en esta memoria descriptiva hace referencia a cualquiera de esos cuatro tipos de JSON primitivos. El término "Estructurado" hace referencia a cualquiera de los tipos JSON estructurados. Cada vez que este documento hace referencia a cualquier tipo JSON, la primera letra siempre está en mayúscula: Objeto, Matriz, Cadena, Número, Booleano, Nulo. Verdadero y Falso también aparecen en mayúsculas.

Todos los nombres de miembros intercambiados entre el Cliente y el Servidor que se tengan en cuenta para cualquier tipo de correspondencia deben distinguir entre mayúsculas y minúsculas. Los términos función, método y procedimiento pueden considerarse intercambiables.

El Cliente se define como el origen de los objetos Solicitud y el gestor de los objetos Respuesta.
 El Servidor se define como el origen de los objetos Respuesta y el gestor de los objetos de Solicitud.

 Una implementación de esta especificación podría fácilmente desempeñar ambos papeles, incluso al mismo tiempo, para otros clientes diferentes o para el mismo cliente. Esta especificación no aborda esa capa de complejidad.

Compatibilidad

Es posible que los objetos de Solicitud y Respuesta JSON-RPC 2.0 no funcionen con los clientes o servidores JSON-RPC 1.0 existentes. No obstante, resulta sencillo distinguir entre las dos versiones, puesto que la 2.0 siempre tiene un miembro denominado "jsonrpc" con un valor de cadena "2.0", mientras que la 1.0 no lo tiene. La mayoría de las implementaciones de la versión 2.0 deberían plantearse tratar de manejar los objetos de la versión 1.0, aunque no los aspectos P2P y de sugerencia de clases de la versión 1.0.

Objeto de Solicitud

Una llamada rpc se representa enviando un objeto de Solicitud a un Servidor. El objeto de Solicitud tiene los siguientes miembros:

jsonrpc: una cadena que especifica la versión del protocolo JSON-RPC. DEBE ser exactamente "2.0".

método: una Cadena que contiene el nombre del método que se va a invocar. Los nombres de métodos que empiezan por la palabra rpc seguida de un punto (U+002E o ASCII 46) están reservados para métodos y extensiones internas de rpc y NO DEBEN usarse para nada más.

Parámetros: valor estructurado que contiene los valores de los parámetros que se usarán durante la invocación del método. Este elemento PUEDE omitirse.

ID: un identificador establecido por el Cliente que DEBE contener una Cadena, Número o valor NULO si se incluye. Si no se incluye, se supone que es una notificación. El valor normalmente no DEBE ser Nulo [1] y los números NO DEBEN contener partes fraccionarias [2]

El Servidor DEBE responder con el mismo valor en el objeto de Respuesta si se incluye. Este miembro se emplea para correlacionar el contexto entre los dos objetos.

[1] Se desaconseja el uso de un valor Nulo para el miembro id en un objeto de Solicitud, puesto que esta especificación usa un valor Nulo para Respuestas con un id desconocido. Además, dado que JSON-RPC 1.0 usa un valor id de Nulo para las Notificaciones, esto podría causar confusión en el manejo.

[2] Las partes fraccionarias pueden ser problemáticas, puesto que muchas fracciones decimales no pueden representarse exactamente como fracciones binarias.

Notificación

Una Notificación es un objeto de Solicitud sin un miembro "id". Un objeto de Solicitud que es una Notificación indica la falta de interés del Cliente en el objeto de Respuesta correspondiente, y como tal no es necesario devolver ningún objeto de Respuesta al cliente. El servidor NO DEBE responder a una notificación, incluidas las que se encuentran dentro de una solicitud por lotes.

Las notificaciones no son confirmables por definición, puesto que no tienen un objeto de Respuesta para ser devuelto. Como tal, el Cliente no sería consciente de ningún error (por ejemplo, "Parámetros no válidos", "Error interno").

Estructuras de parámetros

Si están presentes, los parámetros para la llamada rpc DEBEN proporcionarse como un valor estructurado. Ya sea por posición a través de una Matriz o por nombre a través de un Objeto.

  • Por posición: los parámetros DEBEN ser una matriz que contenga los valores en el orden esperado por el servidor.

  • Por nombre: los parámetros DEBEN ser un objeto, con nombres de miembros que coincidan con los nombres de parámetros esperados por el servidor. La ausencia de nombres esperados PUEDE dar lugar a que se genere un error. Los nombres DEBEN coincidir exactamente, incluyendo mayúsculas y minúsculas, con los parámetros esperados del método.

Objeto de Respuesta

Cuando se efectúa una llamada rpc, el Servidor DEBE responder con una Respuesta, excepto en el caso de las Notificaciones. La Respuesta se expresa como un único Objeto JSON, con los siguientes miembros:

jsonrpc: Una cadena que especifica la versión del protocolo JSON-RPC. DEBE ser exactamente "2.0".

Resultado: este miembro es OBLIGATORIO
 en caso de éxito.
 El valor de este miembro viene determinado por el método invocado en el servidor.

Error: este miembro es OBLIGATORIO en caso de error.
 Este miembro NO DEBE existir si no se ha producido ningún error durante la invocación.
 El valor de este miembro DEBE ser un objeto tal como se define en la sección 5.1.

ID: este miembro es OBLIGATORIO y DEBE
 ser el mismo que el valor del miembro id en el objeto de solicitud.
 Si ha habido un error al detectar el id en el objeto de solicitud (por ejemplo, un error de análisis sintáctico o una solicitud no válida), DEBE ser nulo.

Se DEBE incluir el miembro de resultado o el miembro de error, pero NO se DEBEN incluir ambos miembros.

Objeto de error

Cuando una llamada rpc encuentra un error, el objeto de Respuesta DEBE contener el miembro error con un valor que sea un Objeto con los siguientes miembros:

Código: número que especifica el tipo de error que se ha producido y
 que DEBE ser un número entero.

Mensaje: una Cadena que brinda una breve descripción del error.
 El mensaje DEBE limitarse a una sola oración concisa.

Datos: un valor Primitivo o Estructurado que contiene información adicional acerca del error.
 Esto puede omitirse.
 El valor de este miembro es definido por el servidor (por ejemplo, información detallada de errores, errores anidados, etc.).

Los códigos de error comprendidos entre -32768 y -32000 están reservados para errores predefinidos. Cualquier código dentro de este rango, pero no definido explícitamente a continuación se reserva para uso futuro. Los códigos de error son casi los mismos que los sugeridos para XML-RPC en la siguiente URL: http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php

código mensaje significado
-32700 Error de análisis El servidor ha recibido un JSON no válido.
Se ha producido un error en el servidor al analizar el texto JSON.
-32600 Solicitud no válida El JSON enviado no es un objeto de Solicitud válido.
-32601 Método no encontrado El método no existe / no está disponible.
-32602 Parámetro no válido Parámetro(s) de método no válido(s).
-32603 Error interno Error interno JSON-RPC.
-32099 to -32000 Error del servidor Reservado para errores de servidor definidos por la implementación.

El resto del espacio está disponible para errores definidos por la aplicación.

Lote

Para enviar varios objetos de Solicitud al mismo tiempo, el Cliente PUEDE enviar una Matriz llena de objetos de Solicitud.

El Servidor debe responder con una Matriz que contenga los objetos Respuesta correspondientes, después de que todos los objetos Solicitud del lote se hayan procesado. Un objeto de Respuesta DEBERÍA existir para cada objeto de Solicitud, excepto que NO DEBERÍA haber ningún objeto de Respuesta para notificaciones. El Servidor PUEDE procesar una llamada rpc por lotes como un conjunto de tareas concurrentes, procesándolas en cualquier orden y con cualquier ancho de paralelismo.

Los objetos de Respuesta que se devuelven de una llamada por lotes PUEDEN devolverse en cualquier orden dentro de la Matriz. El Cliente DEBERÍA hacer coincidir los contextos entre el conjunto de objetos de Solicitud y el conjunto resultante de objetos de Respuesta basándose en el miembro id dentro de cada Objeto.

Si la propia llamada rpc por lotes no se reconoce como un JSON válido o como una Matriz con al menos un valor, la respuesta del Servidor DEBE ser un único objeto de Respuesta. Si no hay objetos de Respuesta contenidos dentro de la Matriz de Respuesta tal y como va a ser enviada al cliente, el servidor NO DEBE devolver una Matriz vacía y no debe devolver nada en absoluto.

Ejemplos

sintaxis:

--> datos enviados al Servidor
<-- datos enviados al Cliente

llamada rpc con parámetros posicionales:

--> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
<-- {"jsonrpc": "2.0", "result": 19, "id": 1}

--> {"jsonrpc": "2.0", "method": "subtract", "params": [23, 42], "id": 2}

<-- {"jsonrpc": "2.0", "result": -19, "id": 2}

llamada rpc con parámetros con nombre:

--> {"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}
<-- {"jsonrpc": "2.0", "result": 19, "id": 3}
--> {"jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 42, "subtrahend": 23}, "id": 4}

<-- {"jsonrpc": "2.0", "result": 19, "id": 4}

una Notificación:

--> {"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]}
--> {"jsonrpc": "2.0", "method": "foobar"}

llamada rpc de método no existente:

--> {"jsonrpc": "2.0", "method": "foobar", "id": "1"}
<-- {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Procedure not found."}, "id": "1"}

llamada rpc con JSON no válido:

--> {"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz]
<-- {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error."}, "id": null}

llamada rpc con objeto de Solicitud no válido:

--> {"jsonrpc": "2.0", "method": 1, "params": "bar"}
<-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": null}

llamada rpc por Lotes, JSON no válido:

--> [ {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},{"jsonrpc": "2.0", "method" ]
<-- {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error."}, "id": null}

rpc con una Matriz vacía:

--> [] 
<-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": null}

llamada rpc con un Lote no válido (pero no vacío):

--> [1]
<-- [ {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": null} ]

llamada rpc con lote no válido:

--> [1,2,3]
<-- [
 {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": null}, 
 {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": null}, 
 {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": null} 
]

Llamada rpc por Lotes:

--> [
 {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
 {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
 {"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},
 {"foo": "boo"},
 {"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},
 {"jsonrpc": "2.0", "method": "get_data", "id": "9"} 
]
<-- [
 {"jsonrpc": "2.0", "result": 7, "id": "1"},
 {"jsonrpc": "2.0", "result": 19, "id": "2"},
 {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": null},
 {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found."}, "id": "5"},
 {"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"}
]

Llamada rpc por Lotes (todas las notificaciones):

--> [
 {"jsonrpc": "2.0", "method": "notify_sum", "params": [1,2,4]},
 {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
]
<-- //No se devuelve nada para todos los lotes de notificación

Extensiones

Los nombres de métodos que comienzan por rpc. están reservados para extensiones del sistema, y NO DEBEN emplearse para ninguna otra cosa. Cada extensión del sistema se define en una especificación relacionada. Todas las extensiones del sistema son OPCIONALES.


Copyright (C) 2007-2010 por el Grupo de Trabajo JSON-RPC

Este documento y sus traducciones pueden usarse para implementar JSON-RPC, puede copiarse y proporcionarse a otros, y pueden prepararse, copiarse, publicarse y distribuirse, total o parcialmente, trabajos derivados que lo comenten o expliquen de otro modo o que ayuden a su implementación, sin restricción de ningún tipo, siempre que se incluya el aviso de copyright anterior y este párrafo en todas esas copias y trabajos derivados. Sin embargo, este documento no podrá modificarse de ningún modo.

Los permisos limitados concedidos anteriormente son perpetuos y no se revocarán.

Este documento y la información que contiene se facilitan "TAL CUAL" y se EXCLUYE CUALQUIER GARANTÍA, EXPRESA O IMPLÍCITA, INCLUIDA PERO NO LIMITADA A CUALQUIER GARANTÍA DE QUE EL USO DE LA INFORMACIÓN CONTENIDA EN EL MISMO NO INFRINGIRÁ NINGÚN DERECHO O CUALQUIER GARANTÍA IMPLÍCITA DE COMERCIABILIDAD O IDONEIDAD PARA UN PROPÓSITO PARTICULAR.