Aperçu

JSON-RPC est un protocole d'appel de procédure à distance (RPC) léger et sans état. Cette spécification définit principalement plusieurs structures de données et les règles relatives à leur traitement. Le protocole est indépendant du transport, en ce sens que les concepts peuvent être utilisés au sein d'un même processus, via des sockets, via http, ou dans de nombreux environnements de transmission de messages. Elle utilise JSON (RFC 4627) comme format de données.

Il est conçu pour être simple !

Conventions

Les mots clés "DOIT", "NE DOIT PAS", "EXIGE", "DOIT", "NE DOIT PAS", "DEVRAIT", "NE DEVRAIT PAS", "RECOMMANDÉ", "PEUT", et "FACULTATIF" dans ce document doivent être interprétés comme décrit dans le RFC 2119.

Comme JSON-RPC utilise JSON, il dispose du même système de types (voir http://www.json.org ou RFC 4627). JSON peut représenter quatre types primitifs (chaînes, nombres, booléens et nuls) et deux types structurés (objets et tableaux). Dans la présente spécification, le terme "primitif" fait référence à l'un de ces quatre types JSON primitifs. Le terme "structuré" fait référence à l'un ou l'autre des types JSON structurés. Chaque fois que ce document fait référence à un type JSON, la première lettre est toujours en majuscule : Objet, Tableau, Chaîne, Nombre, Booléen, Nul. True et False prennent également la majuscule.

Tous les noms de membres échangés entre le client et le serveur qui sont pris en compte pour une quelconque correspondance doivent être considérés comme sensibles à la casse. Les termes fonction, méthode et procédure peuvent être considérés comme interchangeables.

Le client est défini comme l'origine des objets de requête et le gestionnaire des objets de réponse.
Le serveur est défini comme l'origine des objets de réponse et le gestionnaire des objets de requête.

Une installation de cette spécification pourrait facilement remplir ces deux rôles, même en même temps, pour d'autres clients différents ou pour le même client. La présente spécification n'aborde pas cette couche de complexité.

Compatibilité

Les objets de requête et de réponse JSON-RPC 2.0 peuvent ne pas fonctionner avec les clients ou serveurs JSON-RPC 1.0 existants. Cependant, il est facile de faire la distinction entre les deux versions, car 2.0 a toujours un membre nommé "jsonrpc" avec une valeur de chaîne de "2.0", ce qui n'est pas le cas de 1.0. La plupart des implémentations 2.0 devraient envisager d'essayer de gérer les objets 1.0, même si les aspects peer-to-peer et class hinting de la version 1.0 ne sont pas pris en compte.

Objet de la requête

Un appel rpc est représenté par l'envoi d'un objet Request à un serveur. L'objet Request possède les membres suivants:

jsonrpc - Une chaîne spécifiant la version du protocole JSON-RPC. Doit être exactement "2.0".

method - Une chaîne contenant le nom de la méthode à invoquer. Les noms de méthode qui commencent par le mot rpc suivi d'un point (U+002E ou ASCII 46) sont réservés aux méthodes et extensions internes à rpc et ne DOIVENT PAS être utilisés pour autre chose.

params - Valeur structurée contenant les valeurs des paramètres à utiliser lors de l'invocation de la méthode. Ce membre PEUT être omis.

id -Un identifiant établi par le client qui DOIT contenir une chaîne, un nombre ou une valeur NULL s'il est inclus. S'il n'est pas inclus, il est supposé être une notification. La valeur NE DOIT normalement pas être nulle [1] et les nombres NE DOIVENT PAS contenir de parties fractionnaires [2]

Le serveur DOIT répondre avec la même valeur dans l'objet Response s'il est inclus. Ce membre est utilisé pour corréler le contexte entre les deux objets.

[1] L'utilisation de Null comme valeur pour le membre id dans un objet Request est déconseillée, car cette spécification utilise une valeur Null pour les réponses dont l'id est inconnu. De plus, comme JSON-RPC 1.0 utilise une valeur d'id nulle pour les notifications, cela pourrait entraîner une confusion dans la gestion.

[2] Les parties fractionnaires peuvent poser problème, car de nombreuses fractions décimales ne peuvent pas être représentées exactement sous forme de fractions binaires.

Notification

Une notification est un objet de requête sans membre "id". Un objet de requête qui est une notification signifie que le client ne s'intéresse pas à l'objet de réponse correspondant et que, par conséquent, aucun objet de réponse ne doit être renvoyé au client. Le serveur NE DOIT PAS répondre à une notification, y compris à celles qui font partie d'une requête par lots.

Par définition, les notifications ne peuvent pas être confirmées, puisqu'elles n'ont pas d'objet Response à renvoyer. Le client n'est donc pas informé d'éventuelles erreurs (telles que "Paramètres non valides", "Erreur interne").

Structures des paramètres

S'ils sont présents, les paramètres de l'appel rpc DOIVENT être fournis sous la forme d'une valeur structurée. Soit par position dans un tableau, soit par nom dans un objet.

  • by-position : params DOIT être un tableau, contenant les valeurs dans l'ordre attendu par le serveur.
  • by-name : params DOIT être un objet dont les noms des membres correspondent aux noms des paramètres attendus par le serveur. L'absence de noms attendus PEUT entraîner une erreur. Les noms DOIVENT correspondre exactement, y compris la casse, aux paramètres attendus de la méthode..

Objet de la réponse

Lorsqu'un appel rpc est effectué, le serveur DOIT répondre par une réponse, sauf dans le cas des notifications. La réponse est exprimée sous la forme d'un objet JSON unique, avec les membres suivants.

jsonrpc - Une chaîne spécifiant la version du protocole JSON-RPC. Doit être exactement "2.0".

result - Ce membre est OBLIGATOIRE en cas de succès.
Ce membre NE DOIT PAS exister en cas d'erreur lors de l'invocation de la méthode.
La valeur de ce membre est déterminée par la méthode invoquée sur le serveur.

error - Ce membre est OBLIGATOIRE en cas d'erreur.
Ce membre NE DOIT PAS exister si aucune erreur n'a été déclenchée lors de l'invocation.
La valeur de ce membre DOIT être un objet tel que défini à la section 5.1..

id - Ce membre est OBLIGATOIRE.
Il DOIT être identique à la valeur du membre id dans l'objet de la demande.
En cas d'erreur dans la détection de l'identifiant dans l'objet de la demande (par exemple, erreur d'analyse ou demande invalide), il DOIT être nul..

Either the result member or error member MUST be included, but both members MUST NOT be included.

Objet d'erreur

Lorsqu'un appel rpc rencontre une erreur, l'objet réponse DOIT contenir le membre erreur avec une valeur qui est un objet avec les membres suivants:

code - Un nombre qui indique le type d'erreur qui s'est produit.
Il DOIT s'agir d'un nombre entier.

message - Une chaîne de caractères décrivant brièvement l'erreur.
Le message DEVRAIT se limiter à une seule phrase concise.

data - Une valeur primitive ou structurée qui contient des informations supplémentaires sur l'erreur.
Cette valeur peut être omise.
La valeur de ce membre est définie par le serveur (par exemple, informations détaillées sur l'erreur, erreurs imbriquées, etc.)

Les codes d'erreur compris entre -32768 et -32000 sont réservés à des erreurs prédéfinies. Tout code compris dans cette plage, mais non défini explicitement ci-dessous, est réservé pour une utilisation future. Les codes d'erreur sont presque les mêmes que ceux proposés pour XML-RPC à l'adresse suivante :​​​​​​​ http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php

code message description
-32700 Parse error Le serveur a reçu un JSON non valide.
Une erreur s'est produite sur le serveur lors de l'analyse du texte JSON.
-32600 Invalid Request Le JSON envoyé n'est pas un objet de requête valide.
-32601 Method not found La méthode n'existe pas / n'est pas disponible.
-32602 Invalid params Paramètre(s) de méthode non valide(s).
-32603 Internal error Erreur interne JSON-RPC.
-32099 to -32000 Server error Réservé aux erreurs de serveur définies par l'implémentation.

Le reste de l'espace est disponible pour les erreurs définies par l'application.

Lot

Pour envoyer plusieurs objets de requête en même temps, le client PEUT envoyer un tableau rempli d'objets de requête.

Le serveur doit répondre par un tableau contenant les objets Response correspondants, une fois que tous les objets de requête du lot ont été traités. Un objet Réponse DEVRAIT exister pour chaque objet Requête, sauf qu'il NE DEVRAIT PAS y avoir d'objets Response pour les notifications. Le serveur PEUT traiter un appel rpc par lot comme un ensemble de tâches concurrentes, en les traitant dans n'importe quel ordre et avec n'importe quelle largeur de parallélisme.

Les objets Réponse renvoyés lors d'un appel batch PEUVENT être renvoyés dans n'importe quel ordre dans le tableau. Le client DEVRAIT faire correspondre les contextes entre l'ensemble des objets de requête et l'ensemble des objets de réponse qui en résulte, en se basant sur le membre id de chaque objet.

Si l'appel rpc par lots lui-même n'est pas reconnu comme un JSON valide ou comme un tableau avec au moins une valeur, la réponse du serveur DOIT être un objet Réponse unique. Si aucun objet Response n'est contenu dans le tableau Response tel qu'il doit être envoyé au client, le serveur NE DOIT PAS renvoyer un tableau vide et ne doit rien renvoyer du tout.

Exemples

Syntaxe:

--> data sent to Server
<-- data sent to Client

appel rpc avec des paramètres positionnels:

--> {"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}

appel rpc avec des paramètres nommés:

--> {"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}

une notification:

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

appel rpc d'une méthode inexistante:

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

appel rpc avec JSON invalide:

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

Appel rpc avec un objet de requête invalide:

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

appel rpc Lot, JSON invalide:

--> [ {"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}

appel rpc avec un tableau vide:

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

appel rpc avec un lot invalide (mais non vide):

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

Appel rpc avec un lot invalide:

--> [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} 
]

appel rpc Lot:

--> [
 {"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"}
]

Appel rpc Batch (toutes les notifications):

--> [
 {"jsonrpc": "2.0", "method": "notify_sum", "params": [1,2,4]},
 {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
]
<-- //Nothing is returned for all notification batches

Extensions

Les noms de méthodes commençant par rpc. sont réservés aux extensions du système et ne DOIVENT PAS être utilisés pour autre chose. Chaque extension de système est définie dans une spécification connexe. Toutes les extensions de système sont OPTIONNELLES.


Copyright (C) 2007-2010 par le groupe de travail JSON-RPC

Ce document et ses traductions peuvent être utilisés pour mettre en œuvre JSON-RPC, il peut être copié et fourni à d'autres, et des travaux dérivés qui le commentent ou l'expliquent d'une autre manière ou qui aident à sa mise en œuvre peuvent être préparés, copiés, publiés et distribués, en totalité ou en partie, sans restriction d'aucune sorte, à condition que l'avis de copyright ci-dessus et le présent paragraphe soient inclus dans toutes ces copies et travaux dérivés. Toutefois, le présent document lui-même ne peut être modifié de quelque manière que ce soit.

Les autorisations limitées accordées ci-dessus sont perpétuelles et ne seront pas révoquées.

Le présent document et les informations qu'il contient sont fournis "en l'état" et toutes les garanties, explicites ou implicites, sont exclues, y compris, mais sans s'y limiter, toute garantie selon laquelle l'utilisation des informations contenues dans le présent document n'enfreindra aucun droit ou toute garantie implicite de qualité marchande ou d'adéquation à un usage particulier.