<?xml version="1.0" encoding="UTF-8"?>
<?rfc toc="yes"?>
<?rfc symrefs="yes"?>
<?rfc tocindent="no"?>
<?rfc toc="yes"?>
<?rfc symrefs="yes"?>
<?rfc tocindent="no"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY RFC7159 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7159.xml">
<!ENTITY RFC7493 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7493.xml">
<!ENTITY RFC2119 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC7950 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7950.xml">
<!ENTITY RFC7230 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7230.xml">
<!ENTITY RFC7951 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7951.xml">
]>
<rfc docName="draft-yang-json-rpc-01" ipr="trust200902" category="info">
  <front>
    <title abbrev="0">Application of YANG Modeling to JSON RPCs for Interoperability Purposes</title>
    <author initials="A." surname="Ivanov" fullname="Anton Ivanov">
      <organization abbrev="Brocade">Cambridge Greys Limited</organization>
      <address>
        <email>anton.ivanov@cambridgegreys.com</email>
      </address>
    </author>
    <author initials="D." surname="Spence" fullname="David Spence">
      <organization abbrev="Brocade">Brocade Communications Systems, Inc.</organization>
      <address>
        <email>david@roughsketch.co.uk</email>
      </address>
    </author>
    <author initials="S." surname="Saxena" fullname="Shaleen Saxena">
      <organization abbrev="Brocade">Brocade Communications Systems, Inc.</organization>
      <address>
        <postal>
          <street>130 Holger Way</street>
          <region>CA</region>
          <code>95134</code>
          <country>USA</country>
        </postal>
        <email>ssaxena@brocade.com</email>
      </address>
    </author>
    <author initials="T." surname="Nadeau" fullname="Tom Nadeau">
      <organization abbrev="Brocade">Brocade Communications Systems, Inc.</organization>
      <address>
        <email>tnadeau@lucidvision.com</email>
      </address>
    </author>
    <date month="August" year="2017"/>
    <area>Operations and Management
</area>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <t>This document specifies the application of YANG modeling language to JSON RPC 2.0 for the purposes of achieving interoperability between implementations.</t>
    </abstract>
  </front>
  <middle>
    <section title="Introduction" anchor="d1e404">
      <t>A key use case for JSON encoding of data is the transfer and interchange of such data between applications. While some of the semantics desribed here will be of value for any such interchange, this document will concentrate on two specific use cases - Remote Procedure Calls (RPCs) and Notifications. There is a standard specification for using JSON in both - it is the JSON RPC 2.0 specification maintained by JSON RPC working group at jsonrpc.org <xref target="JSONRPC20"/>. This specification uses JSON as described in <xref target="RFC7159"/> in messages transported over a variety of transports. For example - HTTP <xref target="RFC7230"/>, 0MQ <xref target="ZEROMQ"/>, AMQP <xref target="AMQP"/> etc. </t>
      <t>The JSON RPC 2.0 specification <xref target="JSONRPC20"/> has a number of well known shortcomings. There are no means of describing and documenting a particular API method. There are no means to specify how to interpret data received via an RPC call or notification and what data structures should be generated to accommodate the data. Most implementers have concentrated on the loss of data structure information as a key deficiency, while ignoring the lack of API description which is the actual root cause. This has led them to encode information about the data structures into bespoke extensions also known as class hints and/or use of special “magic” method notations as implemented in <xref target="JABSORB"/>, <xref target="PJ0MQ"/>, etc. These break the core assumption of JSON being a language agnostic interchange format and result in a plethora of subtly incompatible JSON RPC implementations.</t>
      <t>This document proposes an alternative to class hints and other non-interoperable extensions through the use of "JSON Encoding of Data Modeled with YANG" RFC <xref target="RFC7951"/> and YANG modeling of JSON RPCs.</t>
    </section>
    <section title="Terminology and Notation" anchor="d1e466">
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in <xref target="RFC2119"/>.</t>
      <t>YANG is the data modeling language as described in <xref target="RFC7950"/>, version 1.1
</t>
      <t>JSON encoding of YANG modeled data structures is described in <xref target="RFC7951"/>
</t>
      <t>JSON RPC 2.0 is the Remote Procedure Call and Notifications encoding as described in <xref target="JSONRPC20"/>
</t>
    </section>
    <section title="Modeling of JSON RPC 2.0 Interfaces in YANG" anchor="d1e505">
      <t>All RPCs in a particular API must be described as RPC statements in its corresponding YANG model in accordance to the rules of RFC7950 <xref target="RFC7950"/>, section 7.14, which is expanded to cover JSON RPCs in addition to NETCONF RPCs. The RPC arguments and results must comply to subsections 7.14.2 and 7.14.3 of RFC7950 <xref target="RFC7950"/>.</t>
      <t>All Notifications provided by a particular API must be described as notification statements in its corresponding YANG model in accordance to the rules of RFC7950 <xref target="RFC7950"/>, section 7.15 which is expanded to cover JSON Notifications in addition to NETCONF ones. The JSON Notification payload and substatements must comply to subsection 7.15.1 of RFC7950 <xref target="RFC7950"/>.</t>
      <t>While all applicable YANG statements as specified by RFC7950 <xref target="RFC7950"/> are supported and acceptable in both RPCs and notifications, the use of must, when, leafref and identityref is discouraged to improve interoperability with implementations which use simplistic serialization/deserialization to parse the messages and do not have a fully featured YANG interpreter. The internal mapping of an RPC name to a function call is an implementation detail outside the scope of this document. RPC method names containing characters invalid as a part of a function name in most computing languages are discouraged, but not prohibited.</t>
      <t>All mappings from application data types to JSON representation types MUST use the conventions defined in "JSON Encoding of Data Modeled with YANG" <xref target="RFC7951"/>. The JSON message payload must use the I-JSON profile according to <xref target="RFC7493"/>. </t>
      <t>If an application does not wish to specify the model constraints for a particular RPC argument or Notification payload it must specify the corresponding element as anydata in the YANG model. </t>
      <t>JSON RPC Specification <xref target="JSONRPC20"/> mandates that positional arguments are always represented as a list even if an RPC call or Notification has a single argument.</t>
      <t>For example, if an RPC is modelled as:</t>
      <t>
        <figure anchor="magicparlabel-329" title="">
          <artwork>grouping arg-uri {
	leaf uri {
		description "A test URI.";             
		mandatory true;             
		type inet:uri;
	}
} 
rpc test-uri {
	description "A simple example RPC.";         
	input {
		uses arg-uri;
	}
} </artwork>
        </figure>
      </t>
      <t>The following payload is invalid - it violates the JSON RPC Specification <xref target="JSONRPC20"/>:</t>
      <t>
        <figure anchor="magicparlabel-353" title="">
          <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"method": "test-uri",
	"params": "http://www.ietf.org"
}</artwork>
        </figure>
      </t>
      <t>The correct parameter encoding is as follows:</t>
      <t>
        <figure anchor="magicparlabel-375" title="">
          <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"method": "test-uri",
	"params": [
		"http://www.ietf.org"
	]
}</artwork>
        </figure>
      </t>
      <t>or</t>
      <t>
        <figure anchor="magicparlabel-397" title="">
          <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"method": "test-uri",
	"params": {
		"uri": "http://www.ietf.org"
	}
}</artwork>
        </figure>
      </t>
      <t>YANG models describing different RPCs and Notifications may be grouped together into a YANG module to describe an API or a set of APIs.</t>
      <section title="Optionality" anchor="d1e654">
        <t>Omitted optional parameters for the positional form of JSON RPC 2.0 <xref target="JSONRPC20"/> must be specified as null elements in the argument array. </t>
        <t>For example, both arguments in the test-elements RPC are optional.</t>
        <t>
          <figure anchor="magicparlabel-429" title="">
            <artwork>rpc test-elements {
	description "A simple example RPC.";         
	input {
		leaf element1 {
			type string;
		}
		leaf element2 {
			type string;
		}
	}
} </artwork>
          </figure>
        </t>
        <t>If only element2 is supplied, the resulting JSON RPC payload using the positional form should be:</t>
        <t>
          <figure anchor="magicparlabel-452" title="">
            <artwork>{
    "id": 3,
    "jsonrpc": "2.0",
    "method": "test-elements",
    "params": [
        null,
        "element2 value"
    ]
} </artwork>
          </figure>
        </t>
        <t>The named form should be:</t>
        <t>
          <figure anchor="magicparlabel-474" title="">
            <artwork>{
	"jsonrpc":"2.0",
	"id":3,
	"method":"test-elements",
	"params":{
		"element2": "element2 value"
	}
}</artwork>
          </figure>
        </t>
        <t>While using the named form can allow an implementation to differentiate between a parameter being supplied and a parameter being null, implementers should not rely on this difference in semantics as most computing language compilers and runtimes will obscure this difference from the caller.</t>
        <t>Trailing nulls resulting from missing parameters or an implementation supplying a null argument MAY be stripped from a call by position payload. The following encoding:</t>
        <t>
          <figure anchor="magicparlabel-498" title="">
            <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"method": "test-elements",
	"params": [
		"element1 value",
		null
	]
}</artwork>
          </figure>
        </t>
        <t>can also be expressed as:</t>
        <t>
          <figure anchor="magicparlabel-520" title="">
            <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"method": "test-elements",
	"params": [
		"element1 value"
	]
}</artwork>
          </figure>
        </t>
      </section>
      <section title="Default values" anchor="d1e757">
        <t>The receiving implementation MUST supply any default values as specified by the model if the sender has omitted them as described in RFC7950 <xref target="RFC7950"/>, section 7.14.2 and 7.14.3. Thus, in a JSON RPC the caller may omit supplying a default value. The callee (the server) implementation is obliged to fill it in prior to passing the data to an application. For example, for the following model:</t>
        <t>
          <figure anchor="magicparlabel-554" title="">
            <artwork>
rpc test-htg-2 {
	description "A simple example RPC.";         
	input {
		leaf question {
			type string; 
			default "Meaning of the Universe";
		}
	}
	output {
		leaf answer {
			type int;
			default 42;
		}
} </artwork>
          </figure>
        </t>
        <t>The test-htg RPC can be invoked with the following payload:</t>
        <t>
          <figure anchor="magicparlabel-574" title="">
            <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"method": "test-htg-2",
	"params": []
}</artwork>
          </figure>
        </t>
        <t>The receiver implementation MUST fill the value of “Meaning of the Universe” before passing the parsed payload to the application. The application is not obliged to supply the answer of 42. If the application does not supply an answer, the model aware JSON RPC2.0 implementation must add it to the payload prior to it being sent to the caller as an RPC result.</t>
      </section>
      <section title="The idl:value-type YANG Extension" anchor="d1e806">
        <t>This document standardizes a new YANG extension idl:value-type compliant to <xref target="RFC7950"/>. This extension specifies additional metadata necessary for a source code generator to produce the correct source code mapping for a specific YANG type. The value provided by the idl:value-type extension is a type hint for the generator and may refine or override the standard type mapping rules specified in "JSON Encoding of Data Modeled with YANG" <xref target="RFC7951"/>. For example:</t>
        <t>
          <figure anchor="magicparlabel-601" title="">
            <artwork>idl:value-type python {
	idl:implemented-by bsct.enforce.value.TypeBoolean;
}</artwork>
          </figure>
        </t>
      </section>
      <section title="Modeling of JSON RPC 2.0 RPCs" anchor="d1e840">
        <section title="Representing results" anchor="d1e845">
          <t>In order to simplify integration to existing codebase, RPC calls returning a single result MUST emit a single value for the params key in the RPC message instead of a an array consisting of a one element for the positional form of JSON RPC 2.0 for the cases where it is non-ambiguous, namely lists, leaf-lists and all primitive types. </t>
          <t>For example, invoking the test-1 RPC in the following example</t>
          <t>
            <figure anchor="magicparlabel-625" title="">
              <artwork>rpc test-1 {
	description "A simple example RPC.";         
	output {
		leaf answer {
			type int;
		}
} </artwork>
            </figure>
          </t>
          <t>will produce a simplified result:</t>
          <t>
            <figure anchor="magicparlabel-644" title="">
              <artwork>{
    "id": 3,
    "jsonrpc": "2.0",
    "result": 42
} </artwork>
            </figure>
          </t>
          <t>This simplification is ambiguous for anydata and container result types. If an RPC call uses the positional form to represent a container or anydata return value, it MUST represent it as an array with a single element equal to the result value.</t>
          <t>For example, invoking the test-2 RPC in the following example</t>
          <t>
            <figure anchor="magicparlabel-666" title="">
              <artwork>rpc test-2 {
	description "A simple example RPC.";         
	output {
		leaf answer {
			type anydata;
		}
} </artwork>
            </figure>
          </t>
          <t>will produce a verbose result:</t>
          <t>
            <figure anchor="magicparlabel-687" title="">
              <artwork>{
    "id": 3,
    "jsonrpc": "2.0",
    "result": [
		{"key":"value"}
	]
} </artwork>
            </figure>
          </t>
        </section>
        <section title="Modeling and expressing in JSON of data structures fully described by model" anchor="d1e925">
          <t>All data structures for which the model is known should be fully described in YANG as specified in <xref target="RFC7950"/>. The test-uri RPC in the following example is expecting a uri argument. The uri argument is fully described and modeled:</t>
          <t>
            <figure anchor="magicparlabel-724" title="">
              <artwork>grouping arg-uri {
	leaf uri {
		description "A test URI.";             
		mandatory true;             
		type inet:uri;
	}
} 
rpc test-uri {
	description "A simple example RPC.";         
	input {
		uses arg-uri;
	}
	output {
		leaf passes {
			type boolean;
		}
	}
} </artwork>
            </figure>
          </t>
          <t>The output is a boolean signifying if the test has passed or has failed. For a URI value of “http://www.ietf.org”, this corresponds to the following JSON RPC request payload when using positional arguments:</t>
          <t>
            <figure anchor="magicparlabel-744" title="">
              <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"method": "test-uri",
	"params": ["http://www.ietf.org"]
}</artwork>
            </figure>
          </t>
          <t>Alternatively, when using named arguments</t>
          <t>
            <figure anchor="magicparlabel-766" title="">
              <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"method": "test-uri",
	"params": {
		"uri": "http://www.ietf.org"
	}
}</artwork>
            </figure>
          </t>
          <t>If we assume that the remote procedure call with an argument of “http://www.ietf.org” returns True, we will have the following result. Positional form:</t>
          <t>
            <figure anchor="magicparlabel-785" title="">
              <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"result": true
}</artwork>
            </figure>
          </t>
          <t>Named form:</t>
          <t>
            <figure anchor="magicparlabel-806" title="">
              <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"result": {
		"passes": true
	}
}</artwork>
            </figure>
          </t>
        </section>
        <section title="Modeling and expressing in JSON of data structures with elements outside model scope" anchor="d1e1022">
          <t>Structures which the implementer does not wish to model in YANG (from here on referred to as “opaque”) are specified as anydata. For example the test-object RPC expects an object argument and returns an object output. The argument and the return are opaque to the model and may contain nested structures or structures which the implementer has decided to keep outside the scope of the model.</t>
          <t>
            <figure anchor="magicparlabel-837" title="">
              <artwork>grouping arg-object {
	leaf object {
		description "A test Object.";             
		mandatory true;             
		type anydata;
	}
} 
rpc test-object {
	description "A simple example RPC.";         
	input {
		uses arg-object;
	}
	output {
		uses arg-object;
	}
} </artwork>
            </figure>
          </t>
          <t>Objects opaque to the model as in this example are encoded as JSON using the rules for anydata in <xref target="RFC7951"/>
</t>
          <t>For an object value of {”key”:”value”}, this corresponds to the following JSON RPC request payload when using positional arguments:</t>
          <t>
            <figure anchor="magicparlabel-864" title="">
              <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"method": "test-object",
	"params":[
		{"key": "value"}
	]
}</artwork>
            </figure>
          </t>
          <t>Alternatively, when using named arguments</t>
          <t>
            <figure anchor="magicparlabel-888" title="">
              <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"method": "test-object",
	"params": {
		"object":{
			"key": "value"
		}
	}
}</artwork>
            </figure>
          </t>
          <t>If we assume that the procedure call returns the following test-object [“eeny”, “meeny”, “miny”, “moe”], we will have the following result. Positional form:</t>
          <t>
            <figure anchor="magicparlabel-912" title="">
              <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"result": [
		"eeny",
		"meeny",
		"miny",
		"moe"
	]
}</artwork>
            </figure>
          </t>
          <t>Named form:</t>
          <t>
            <figure anchor="magicparlabel-938" title="">
              <artwork>{
	"jsonrpc": "2.0",
	"id": 3,
	"result": {
		"object": [
			"eeny",
			"meeny",
			"miny",
			"moe"
		]
	}
}</artwork>
            </figure>
          </t>
        </section>
      </section>
      <section title="Modeling of JSON RPC 2.0 Notifications" anchor="d1e1121">
        <section title="Modeling and expressing in JSON of notifications with fully modeled data payload" anchor="d1e1126">
          <t>All data structures for which the model is known should be fully described in YANG as specified in <xref target="RFC7950"/>. The testing Notification in the following example contains a uri leaf. The notification server issuing the notification is expected to supply the value and the recipients will expect the value for this leaf:</t>
          <t>
            <figure anchor="magicparlabel-969" title="">
              <artwork>grouping arg-uri {
	leaf uri {
		description "A test URI.";             
		mandatory true;             
		type inet:uri;
	}
} 
notification notify-uri {
	description "A simple notification with URI payload.";         
	uses arg-uri;
} </artwork>
            </figure>
          </t>
          <t>This results in the following notification payloads. Positional arguments:</t>
          <t>
            <figure anchor="magicparlabel-990" title="">
              <artwork>{
	"jsonrpc": "2.0",
	"method": "notify-uri",
	"params": [
		"http://www.ietf.org"
	]
}</artwork>
            </figure>
          </t>
          <t>Note - there is no id member in a notification. Alternatively, when using named arguments</t>
          <t>
            <figure anchor="magicparlabel-1011" title="">
              <artwork>{
	"jsonrpc":"2.0",
	"method": "notify-uri",
	"params": {
		"uri": "http://www.ietf.org"
	}
}</artwork>
            </figure>
          </t>
        </section>
        <section title="Modeling and expressing in JSON of notifications with data payload outside model scope" anchor="d1e1189">
          <t>Structures which the implementer does not wish to model in YANG and pass as object are specified as anydata. For example the notify-object notification expects an object argument as its object leaf.</t>
          <t>
            <figure anchor="magicparlabel-1038" title="">
              <artwork>grouping arg-object {
	leaf object {
		description "A test Object.";             
		mandatory true;             
		type anydata;
	}
} 
notification notify-object {
	description "A simple Notification with an 
		opaque object payload.";         
	uses arg-object;
} </artwork>
            </figure>
          </t>
          <t>Objects opaque to the model as in this example are encoded as JSON using the rules for anydata in <xref target="RFC7951"/> resulting in the following example payloads for the {”key”:”value”} object payload:</t>
          <t>
            <figure anchor="magicparlabel-1065" title="">
              <artwork>{
	"jsonrpc": "2.0",
	"method": "notify-object",
	"params": [
		{
			"key": "value"
		}
	]
}</artwork>
            </figure>
          </t>
          <t>Note - there is no id member in a notification. Alternatively, when using named arguments</t>
          <t>
            <figure anchor="magicparlabel-1088" title="">
              <artwork>{
	"jsonrpc": "2.0",
	"method": "notify-object",
	"params": {
		"object": {
			"key": "value"
		}
	}
}</artwork>
            </figure>
          </t>
        </section>
      </section>
      <section title="Addressing Modeled Data - Yang Paths" anchor="d1e1252">
        <t>When working with structured data in a tree form it is essential to be able to address parts of the tree and individual elements. Yang uses Instance Identifiers for this purpose. The current normative reference for this is section 6.1. of <xref target="RFC7951"/>. It borrows the representation from Netconf and represents IIds as an uri path. There are issues with this encoding when used in a JSON RPC context:</t>
        <t>
          <list style="symbols">
            <t>Yang IId is intended only for the purposes of addressing data. It does not provide semantics to address RPCs and/or Notifications and their argument which are the primary target of this specification.</t>
            <t>The representation in section 6.11 of <xref target="RFC7951"/> does not match JSON semantics - it uses URI syntax which requires conversion for each addressing operation. This approach has some advantages for implementations which support netconf and/or XML in parallel with JSON as these have existing URI parsers. It is, however, clearly disadvantageous for any non-netconf implementation, because it introduces a single “foreign” object type with a non-JSON serialization in the middle of a JSON specification. </t>
          </list>
        </t>
        <t>The path specification specified in this draft provides a representation of paths to address Notification and RPC objects as well as paths into data structures. It MUST be explicitly specified as an anydata object in any models and is not a 1:1 replacement representation for an IId.</t>
        <section title="Addressing anything but an individual list element" anchor="sub_Addressing_anything_but">
          <t>Containers, leaves, leaf-lists, lists as a whole (everything but an individual element in a list) have their Path expressed as:</t>
          <t>
            <figure anchor="magicparlabel-1121" title="">
              <artwork>{
	"module:top-level-container": {
		"subcontainer":{}
	}
}</artwork>
            </figure>
          </t>
          <t>The path is represented as a single branch tree structure containing nested JSON objects. Each level key is the QName. Path terminates in {} to signify what is being addressed. </t>
          <t>Module, revision and namespace qualifiers are optional and can be omitted except module qualifier at top level.</t>
        </section>
        <section title="Addressing an individual list element" anchor="sub_Addressing_an_individual">
          <t>Individual list elements have their Paths expressed as:</t>
          <t>
            <figure anchor="magicparlabel-1146" title="">
              <artwork>{
	"module:top-level-container": {
		"list":[{
			"key1":"value1",
			"key2":"value2"
		}]
	}
}</artwork>
            </figure>
          </t>
          <t>Path is represented as a single branch tree structure containing nested JSON objects up to the list level.</t>
          <t>At list level the QName is followed by [] to signify a list. The list contains a single object with key-value pairs uniquely identifying the list element.</t>
        </section>
        <section title="Addressing inside an individual list element" anchor="d1e1342">
          <t>Individual list elements have their Paths expressed as:</t>
          <t>
            <figure anchor="magicparlabel-1172" title="">
              <artwork>{
	"module:top-level-container": {
		"list":[{
			"key1":"value1",
			"key2":"value2",
			"list-element": {}
		}]
	}
}</artwork>
            </figure>
          </t>
          <t>This form is obtained by adding a path as described in  <xref target="sub_Addressing_anything_but"/> section to the list element IId representation described in  <xref target="sub_Addressing_an_individual"/>.</t>
        </section>
      </section>
    </section>
  </middle>
  <back>
    <references title="Normative References">&RFC7159;
&RFC7493;
&RFC2119;
&RFC7950;
&RFC7230;
&RFC7951;
<reference anchor="ZEROMQ" target="http://zeromq.org"><front><title abbrev="Zero MQ Home Page">Zero MQ</title><author/><date/></front></reference> <reference anchor="AMQP" target="https://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf"><front><title abbrev="AMQP Protocol Specification">AMQP Protocol Specification</title><author/><date/></front></reference> <reference anchor="JSONRPC20" target="http://www.jsonrpc.org/specification"><front><title abbrev="JSON RPC 2.0">JSON-RPC 2.0 Specification</title><author initials="M." surname="Morley" fullname="Matt Morley"><organization>JSON-RPC google group</organization><address><email>matt@mpcm.com</email></address></author><date year="2010"/></front><format type="HTML" target="http://www.jsonrpc.org/specification"/></reference> <reference anchor="JABSORB" target="http://www.jabsorb.org/"><front><title abbrev="Jabsorb Home Page">Jabsorb JSON RPC Orb and Broker</title><author/><date/></front></reference> <reference anchor="PJ0MQ" target="https://github.com/dwb/jsonrpc2-zeromq-python"><front><title abbrev="Python JSON RPC over 0MQ">Python JSON RPC over 0MQ</title><author/><date/></front></reference> </references>
  </back>
</rfc>
