Package jmri.server.json
Schema
The JMRI JSON protocol has two sets of schema, one for messages from clients to a JMRI server, and one for messages from a JMRI server to clients. The core schema for socket interfaces are the client schema and server schema. These schema define the structure of JSON messages in this protocol. Messages generally containtype
, data
, and
method
properties.
The data object types supported in a running JMRI instance for both RESTful and socket interfaces can be listed at http://my-jmri-server:12080/json/version/type and individual schema for each data object type at http://my-jmri-server:12080/json/version/schema/type
Methods
The JMRI JSON services accept four methods, all of which directly correspond to HTTP 1.1 methods. The socket services accept one non-HTTP 1.1 method"list"
to
allow the listing of objects (in the HTTP service, this is an HTTP GET). In
the socket implementations, the method is specified using the
"method"
name in the message object
with one of the following values:
- "get"
- Get the requested object. Absent a
"method"
name, this is the default method. Note to developers: this should be an idempotent method. - "post"
- Modify the requested object.
- "put"
- Create the requested object. Note to developers: this should be an idempotent method if the requested object already exists (i.e., this request should not modify an existing object if a new object cannot be created).
- "delete"
- Delete the requested object. Note to developers: This should be an idempotent method if the requested object does not exist.
- "list"
- Used in the socket interfaces to get a list of the given
type
. The equivalent form in the RESTful interface is aGET
request to/json/<version>/<type>
.
Messages
Fundamentally, the JSON server passes messages as JSON Objects between a JMRI server and one or more clients. In the TCP Socket and WebSocket interfaces, a message from the client generally has three properties (full details are in the schema):
type
- The type of object in the data property.
method
- The RESTful method to be used, defaults to get if not present.
data
- The JSON representation of a JMRI object; see the schema for the properties of this object, since the properties vary by type.
id
- A message identity as a positive integer that will be returned unmodified to the client in any messages that are direct responses to the message containing an id. Defaults to zero if not present.
A message from the server is either a single JSON Object
{"type":"type","data":{...}}
except as noted below or a
JSON Array of objects. In the RESTful interface, messages from the client in
POST and PUT requests may contain a JSON object that
corresponds to the data
object in the socket interfaces.
Exceptions
Exceptions to the above form for the socket interfaces are:
- Get Requests
- When using a get method, specifying the method is optional.
- List Requests
- List requests are in the form:
{"type":"type","method":"list","data":{...}}
(recommended) or{"type":"list","list":"type"}
or{"list":"type"}
in the socket interfaces and will either cause an error to be thrown if type is not listable, or cause an array of items to be sent to the client. Thedata
object is not required; some list requests can have additional parameters in thedata
object; however some services ignore that with lists. - List Responses
- List responses are in the form:
[message,message]
, an array of object message types withtype
anddata
properties. There is no guarantee that an array contains all objects of a single type, or that an array contains all of the objects of a single type, since it is, by design, possible for multiple services, including third-party services to respond to a single request, and the JSON server neither makes nor enforces any guarantees concerning how those services respond. Multiple responses are joined together when using JSON via the RESTful interface, and may or may not be joined together when using JSON in other interfaces. - Heartbeats
- Heartbeat messages are sent by the client to assure the JMRI server that
a socket connection is still up. A heartbeat from the client is in the form
{"type":"ping"}
and is answered with a{"type":"pong"}
from the JMRI server. - Closing Sockets
- When a socket is being closed in a non-erroneous way, the system
initiating the close (either a client or server) sends a message
{"type":"goodbye"}
and closes its connection. The receiving system should not respond and close its connection. - Malformed JSON
- When receiving a message with malformed JSON, the JMRI server will not attempt to include an id if present in the malformed message.
Note The name property of a data object
must be the system name, not the user name, of the requested
object (usually a NamedBean
), except when creating an object
using a put
method and the Manager
for that class of
NamedBean supports creating a NamedBean using an automatically generated
system name. It is generally safer to always use system names.
Versions
The running JMRI instance may support multiple major versions of the
JSON protocol. A single JMRI instance will only support one
major.minor.patch
version of the JSON protocol (i.e. a JMRI instance
may support JSON versions 5.3.1 and 6.0.2, but should not be expected to
support JSON version 5.3.1 and 5.4.0). A JMRI instance that supports multiple
versions of the JSON protocol will provide a JSON list of name/value pairs in
response to the HTTP query http://localhost:12080/json/version
. No
Socket equivalent of this URL exists, since the first message (a
hello
message) in the socket stream specifies the version to be used.
The names are the supported versions in major.minor.patch
format and
the values are the HTTP path component ("v" + major
(i.e "v5" for
version 5.3.1)) for using that version. (Web)Socket JSON clients should
specify the required JSON version in the hello
message or in the
WebSocket URL. If a requested version is not specified, the JSON protocol
5.x.y will be used. If a JMRI instance does not support JSON protocol 5, an
error will be returned if the client does not specify the JSON version to
use.
Note until support for using protocol version 5 is dropped, requesting an unsupported version will result in an error with code 404 or 400. Once support for protocol version 5 is dropped all requests for an unsupported version will result in an error with code 400.
Version History
Changes to the major number represent a backwards incompatible change in the
protocol, while changes to the minor number represent an addition to the
protocol, and changes to patch number represent a bug fix within the
protocol. The JSON protocol version is available to clients in the
hello
message. Within test releases between to two production
releases, breaking changes only reset the major number once (for example,
breaking changes in JMRI 4.15.4 to JSON protocol version 4.1 followed by
breaking changes to 5.0.0 in 4.15.6 will result in JMRI release 4.16
including JSON protocol version 5.0.0, not 6.0.0, since 4.15.4 and 4.15.6 are
both between JMRI production releases 4.14 and 4.16).
Starting with 5.0.0, the JSON protocol version follows semantic version rules, prior to that the version is just a major.minor version.
- 5.4.0 (JMRI 4.19.5)
-
- Allows the feedback mode and feedback sensors to be manipulated for turnouts.
- 5.3.0 (JMRI 4.19.2)
-
- Adds
/json/version
RESTful API endpoint to list JSON versions supported by the running JMRI instance. This endpoint is not versioned like other endpoints. - Adds the
version
type the socket APIs to allow a client to query the protocol version currently in use on the socket over which the request was made. - Adds the
version
property tohello
objects to allow a client to specify a preferred version and the server to notify the client of the version in use. - Allows RESTful API endpoints for version 5 to explicitly request a
protocol version using
/json/v#/type/...
or implicitly expect the use of version 5 using/json/type/...
. Versions 6 and newer will always require explicitly requiring the version in RESTful API endpoints.
- Adds
- 5.2.0 (JMRI 4.17.7)
-
- memory and block now return idTag and reporter values as json objects
- for networkService, add userName and change name to mDNS type
- Add configProfile.isNextProfile
- several schema fixes
- reporter.report now supports Reportable data
- fix systemConnection, configProfile, panel to return single item for name
- 5.1.0 (JMRI 4.17.4)
-
- Fixes setting the car type for operations rolling stock
- Adds the settable property "carSubType" to include car type information that is not shown on manifests or switch lists
- 5.0.0 (JMRI 4.15.4 with further changes in 4.15.6)
-
- Adds the ability for a client to specify a message ID that will be included in messages returned in direct response to the identified message
- Adds a framework for allowing a client to delete objects and handle conflicts (mostly object is in use elsewhere types) when deleting objects
- Adds schemas that define valid JSON message for all types except consists; #5002 is being used to track progress on allowing schema validation at all times.
Introduces backwards-incompatible changes of:
- Respecting the requirement that a JSON message object from the client
include a
method
name to not be treated as a "get" introduced in version 4.1. - Removes code that creates listeners for objects not requested by the client
- JSON Operations objects use
name
instead ofid
to match behavior of other JSON objects. - JSON Throttle objects use
name
instead ofthrottle
to match behavior of other JSON objects. - Deprecates, but does not remove, support for plural tokens for listing types, using the singular token syntax introduced in version 3.0.
- 4.1 (JMRI 4.11.4)
- The RESTful method associated with a JSON message from the client absent
a
method
name with a value of "get", "post", "put", or "delete" is assumed to be "get". - 4.0 (JMRI 4.3.4)
- Prior to version 4.0, the JSON servers had a single definition for all tokens used in JSON communications. As of version 4.0, the JSON servers use a modular protocol, fixing as constants only the tokens used for the basic protocol structure as well as some tokens used by multiple modules.
- 3.0 (JMRI 3.11.2)
- Types no longer need be plural to list. This means that RESTful URLs can be /json/type/name for a single object and /json/type for a list of objects, and /json/types is no longer needed to list (i.e. /json/turnout/IT1 gets turnout IT1, and /json/turnout gets the list of turnouts).
- 2.0 (JMRI 3.9.3)
- No reason for version change listed in commit history.
- 1.1 (JMRI 3.7.1)
- No reason for version change listed in commit history.
- 1.0 (JMRI 3.4)
- Initial release of JMRI JSON Protocol.
Notes
The JMRI JSON services are defined using JsonServiceFactory
objects which may be loaded as third-party plug-ins to JMRI (see Plug-in
mechanisms). Because of this the JSON server can make no guarantees
concerning how the JSON services handling a specific type of object behave;
specifically the following are not guaranteed:
- An array response to a list request contains all items of the requested type.
- An array response does not contain duplicate items of the same type with different data.
- The message sent from a JMRI server is in response to the last message received when using sockets.
- Requests for an object will cause a listener to be created for that object such that the client is automatically updated when the object or object state changes.
- Requests for a list will cause a listener to be created that automatically updates the client when objects of a type are added or removed within JMRI.
- A single service will be the only responder to a specific message.
- Since:
- 4.3.4
- See Also:
JsonServlet
,JsonServer
,JsonServiceFactory
-
Class Summary Class Description Bundle JSON Common and utility constants used in the JMRI JSON protocol.JsonClientHandler Handler for JSON messages from a TCP socket or WebSocket client.JsonConnection Abstraction of DataOutputStream and WebSocket.Connection classes for JSON clients.JsonDeleteTokenManager Manager for deletion tokens in the JSON protocols.JsonHttpService Provide HTTP method handlers for JSON RESTful messagesJsonNamedBeanHttpService<T extends NamedBean> Abstract implementation of JsonHttpService with specific support forNamedBean
objects.JsonNamedBeanSocketService<T extends NamedBean,H extends JsonNamedBeanHttpService<T>> Abstract implementation of JsonSocketService with specific support forNamedBean
objects.JsonNonProvidedNamedBeanHttpService<T extends NamedBean> Abstract implementation of JsonHttpService with specific support forNamedBean
objects.JsonRequest Container for data in JSON request.JsonServer This is an implementation of a JSON server for JMRI.JsonServerAction JsonServerPreferences JsonServerPreferencesPanel JsonServerStartupActionFactory JsonSocketService<H extends JsonHttpService> Interface for JSON Services provided over TCP Sockets or WebSockets.JsonWebSocket -
Exception Summary Exception Description JsonException Throw an exception, but include an HTTP error code.