Did you know ... Search Documentation:
json_rpc_server.pl -- JSON RPC Server
PublicShow source

This module implements an JSON RPC server. It provides declarations that bind Prolog predicates to JSON RPC methods and a dispatch loop that acts on a bi-directional stream. This module assumes a two-directional stream and provides json_rpc_dispatch/2 that receiveds JSON messages on the input side of this stream and sends the replies through the output. This module does not implement obtaining such a stream. Obvious candidates for obtaining a stream are:

  • Using standard I/O to a child process. See process_create/3.
  • Using sockets. See library(socket). Using the SSL package this also provides secure sockets.
  • Using the HTTP package to extablish a web socket.

This library defines json_method/1 for declaring predicates to act as a JSON method. The declaration accepts a JSON Schema specification, represented as a SWI-Prolog dict to specify the input parameters as well as the output.

See also
- JSON-RPC
Source json_method(+Methods)
Methods is a comma-list of JSON RPC method declarations. Each declaration takes one of the forms below:
Callable:Reply
Here, Callable is a Prolog callable term whose name and number of argument match a predicate in this module. The arguments are JSON Schema types and Reply is a JSON Schema type.
Callable
Callable is as above, but there is no return value. This implements JSON RPC notifications, i.e., asynchronously processed messages for which we do not wait for a reply.

For example:

:- json_method
    subtract(#{type:number}, #{type:number}): #{type:number}.

subtract(A, B, R) :- R is A-B.

Methods with named arguments can be implemented using a single argument that is an object with specified properties. For example, the program below implements a depositing to a bank account. The method takes an account and amount parameter and returns the new balance. The json_rpc_error/2 throws a JSON RPC application error.

:- json_method
    deposit(#{ properties:
               #{ account: #{type:string},
                  amount:  #{type:number}
                }}): #{type:number},

deposit(Request, Reply),
    #{account: Account, amount: Amount} :< Request =>
    transaction((   retract(account(Account, Old))
                ->  New is Old+Amount,
                    asserta(account(Account, New))
                ;   json_rpc_error(2, "Account does not exist")
                )),
    Reply = New.
Source json_rpc_dispatch(:Stream, +Options) is det
Run the JSON RPC dispatch loop until end of file is reached on Stream.
Arguments:
Stream- is stream pair (see stream_pair/2). Normally, the stream should use utf8 encoding. If the stream is a binary stream, it will be processed as if utf8 encoding is enabled. If it is a text stream the encoding of the stream is respected.
Source json_rpc_dispatch_request(+Module, +Stream, +Request, +Options)
Handle a request that has been read from Stream, possibly sending a reply to Stream.
Source json_rpc_error(+Code, +Message)
Source json_rpc_error(+Code, +Message, +Data)
Normally called from a method implementation to raise an application error.
Arguments:
Code- is an integer. The range -32768 to -32000 is reserved for JSON RPC server errors.
Message- is a short string decribing the error
Data- is optional JSON data that provides context for the error.
Errors
- json_rpc_error(Dict), where Dict contains the JSON RPC defined fields code, message and optionally data.

Re-exported predicates

The following predicates are exported from this file while their implementation is defined in imported modules or non-module files loaded by this module.

Source json_rpc_error(+Code, +Message)
Source json_rpc_error(+Code, +Message, +Data)
Normally called from a method implementation to raise an application error.
Arguments:
Code- is an integer. The range -32768 to -32000 is reserved for JSON RPC server errors.
Message- is a short string decribing the error
Data- is optional JSON data that provides context for the error.
Errors
- json_rpc_error(Dict), where Dict contains the JSON RPC defined fields code, message and optionally data.