Skip to content

Instantly share code, notes, and snippets.

@SReject
Last active June 23, 2023 01:34
Show Gist options
  • Save SReject/57c194719632d0e14c6dae7461b29567 to your computer and use it in GitHub Desktop.
Save SReject/57c194719632d0e14c6dae7461b29567 to your computer and use it in GitHub Desktop.
JSON-Based Invoke, Response, Event overview

Invoke, Response, Event

The goal of the Invoke, Response, Event protocol is to provide a generic meaningful format for communications while providing mechanisms related to querying resources and transmitting state change notifications.


Message Formats

Messages are transmitted as JSON-parsable strings and must conform to one of the message-formats given below.

All format-defined properties are required to be part of the resulting JSON string. If a defined property does not have an applicable value, it's value should default to null.

Implementations must NOT define or rely upon any property not defined in this format. Any message property not defined in this document must be ignored by the recipient.

Recipients of messages containing properties not defined by this document may treat the inbound message as invalid.


Invoke

Invoke messages are used to query or update a remote resource. These messages must always result in a Response from the recipient.

Invoke messages may be processed in any order regardless of the order in which they were received; this is to allow for parallel and asynchronous processing of messages.

Property Type Nullable Description
type "invoke" no Literal text invoke
id number
string
no A unique sender-generated id used to associate messages with the invocation
The id must be unique to other pending innvocations but may be reused once a response has been received.
name string no The resource identifier to query
data Array<any> no A list of values(arguments) to pass to the resource handler
If no values are to be provided to the resource data should be an empty array.

Response

Upon receiving a Invoke message, the recipiant should process the innvocation and respond with a response-message. Responses may be transmitted in any order regardless of order in which the originating requests were received.

Invoke messages that result in a state change that would generate an event should generate the Event as well as the Response

Success

Property Type Nullable Description
type "response" no Literal text response
id number
string
no The id property received with the invoke-message
name "success" no Literal text success
data any yes Resulting value from processing the query

Error

Property Type Nullable Description
type "response" no Literal text response
id number
string
no The id property received with the invoke-message
name "error" no Literal text error
data any yes Error information detailing why the invocation failed

Event

An event-message is used to notify the recipient of a state change. Event-messages infer the sender does not care about the actions taken by recipient as a result of receiving the message.

Property Type Nullable Description
type "event" no Literal text event
id number
string
yes If the event is the result of a received invocation the id should be the id of the invocation otherwise it should be null. This is so clients can filter out events that are the direct result of an invocation
name string no Event name/Notification identifier
data any yes The data accompanying the event

Notes

This is heavily inspired by jsonrpc with a focus on the format and ignoring implementation.

Example Communications

Client sends a 'authorize' invocation to server:

{
    "type": "invoke",
    "id":   "authMe",
    "name": "authorize",
    "data": ["guest"]
}

Server begins processing the authorize innvocation

Client sends an 'add' invocation before server finishes processing the authorize invocation:

{
    "type": "invoke",
    "id":   "add2and3",
    "name": "add",
    "data": [2, 3]
}

Server Responds to 'add' invocation (authorize invocation still pending):

{
    "type": "response",
    "id":   "add2and3",
    "name": "error",
    "data": "not authorized"
}

Server finishes authorizing user:

{
    "type": "response",
    "id":   "authMe",
    "name": "ok",
    "data": null
}

Server broadcasts a message to all clients:

{
    "type": "event",
    "id":   "authMe",
    "name": "userConnect",
    "data": {"type": "guest"}
}

Client resends 'add' invocation:

{
    "type": "invoke",
    "id":   "add2and3again",
    "name": "add",
    "data": [2, 3]
}

Server processes the 'add' invocation and responds:

{
    "type": "response",
    "id":   "add2and3again",
    "name": "ok",
    "data": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment