JSON-Rx is extension of JSON-RPC Compact protocol to allow for subscriptions. Such as WebSocket subscriptions, for example, for GraphQL.
The protocol is bi-directional, so both sides of the protocol can simultaneously initiate as well as respond to requests. Client is the side which initiates the request, and server is the side which responds.
The client can: (1) subscribe; and (2) un-subscribe. The server can: (1) complete the subscription, or (2) send an error, which implicitly also completes the subscription; (3) send data, which keeps the subscription active, and server will still follow up with more data or a complete message.
The semantics are analogous to RxJs observables, where a user can .subscribe()
to an observable and later .unsubscribe()
from it. During the subscription, the observable can emit zero or more values. Observable can also complete, in which case no new data or errors are emitted. Or, observable can error, in which case an error is received and it implicitly completes the observable.
JSON-RPC Compact defines four message types:
Request message
Success (response) message
Error (response) message
Notification message
JSON-Rx extends the message set with two new message types:
Un-subscribe message
Data message
JSON-Rx also renames the first two messages of JSON-RPC Compact as follows:
Request message to Subscribe message
Success message to Complete message
Hence, the JSON-Rx protocol consists of six message types:
Subscribe message
Un-subscribe message
Data message
Complete message
Error message
Notification message
The subscribe message is sent out by the client and starts a subscriptions, client can also follow up at any time with unsubscribe message
Server responds to a subscription with data message; and complete or error message.
Client can also send a notification message at any time.
Subscribe message is defined exactly as Request message in JSON-RPC Compact.
Subscribe message is a 3-tuple, which consists of: (1) message ID; (2) remote method name; (3) JSON parameters. It can also be a 2-tuple if the JSON parameters are omitted, e.g. the method has no arguments.
Message ID must be a positive integer. Usually it is an incrementing counter, which starts from 1 and is incremented with every request.
Remote method name is a string. In must be at least 1 character long, and no longer than 128 characters.
JSON parameters is the third member of the tuple and is a JSON object which represents the arguments for the remote method.
Examples:
Un-subscribe message allows client to stop subscription on the server. Un-subscribe message can be sent at any time. Effectively, this allows to cancel any request or subscription, even without receiving back any data.
Un-subscribe message is a 2-tuple: (1) the first member is always equal to -3
; (2) the second member is the ID of the subscription.
Data message is used by the server to send subscription data to the client. There could be any number of data messages sent. No data messages should be sent, nor accepted, after the subscription received a complete message or error message.
Data message is always a 3-tuple, which consists of: (1) the first member is always -2
; (2) the second member is set to the subscription ID; (3) the third member is a JSON payload.
Data message cannot be a 2-tuple.
Complete message is defined exactly as Success message in JSON-RPC Compact. When complete message is sent out by the server, it notifies the client that the subscription should complete and no further data will be sent out.
Complete message is a 3-tuple. Tuple members are as follows: (1) first member is always 0
and signifies a complete message; (2) second member is the message ID of the request; (3) third member is the response payload in JSON format.
Success response might also be a 2-tuple if it is not expected to ever return anything, i.e. it is a method with side-effects only. If the method is expected to return some response at least in some situations, the third member of the 3-tuple should always be present in every response message.
Examples:
Error message is defined exactly as JSON-RCP Complete error message. When error message is sent out by the server, it notifies the client that the subscription should complete and no further data will be sent out.
Error message is a 3-tuple. It is always a 3-tuple and cannot be be reduced to 2-tuple. Error message 3-tuple is specified as follows: (1) first member is always set to -1
; (2) second member is the message ID of the request message; (3) is the error in JSON format.
The third tuple member is an arbitrary JSON value, specific to the application. Usually it is an object with at least "message"
field.
JSON-Rc notification message is defined exactly as JSON-RPC Compact notification message.
Notification message is a one way message, for which no direct response is expected (at the level of this protocol, although you can still use it to implement a higher level protocol).
Notification message is a 2-tuple, which consists of: (1) first member is a string specifying a remote message; (2) second member is JSON payload.
The first string member must be at least 1 character long and no more than 128 characters in length.
Notification message may also be 1-tuple, in which case semantically it is treated as a notification message without arguments.
Request:
Response:
The complete message returns the response and completes the subscription.
Below is a GraphQL subscription example.
Client can subscribe to timer
GraphQL subscription:
Server would emit timer values periodically:
Client can un-subscribe:
After which client will not accept any in-flight data message, and server removes the subscription state on the server once it receives the message.