A transport layer agnostic implementation of JSON-RPC 2.0.
Batch is not supported.
Behest yields output strings to a block that is provided during the constructor:
inst = Behest.new(logger: logger, name: "server", counter: 42) do |output|
transport.send(output)
endAll of the options are optional:
logger:will default to a null loggername:will default toSecureRandom.hex(4)counter:will default torand(0..2**32-1)
It is necessary to feed messages into the instance somehow:
inst.input(input_from_transport_layer)An instance will by default respond to all the error conditions described in JSON-RPC 2.0.
It is recommended to disable these errors if your instance is behaving primarily as a client.
inst.parse_error_allowed = false
inst.invalid_request_error_allowed = false# yields nil as result
inst.add "test.handler1" do |params|
nil
end
# yields string as result
inst.add "test.handler2" do |params|
"something"
end
# if you need to remove it for some reason
inst.remove "test.handler2"
# returns an invalid params error
inst.add "test.handler3" do |params|
raise Behest::InvalidParamsError
end
# returns an invalid params error (with data)
inst.add "test.handler4" do |params|
raise Behest::InvalidParamsError.new(message: "this will appear in error.data")
end
# returns a bespoke error
inst.add "test.handler5" do |params|
raise Behest::HandlerError.new(42, "some message", another: "message")
end
# returns an internal error
inst.add "test.handler6" do |params|
raise ArgumentError
end
# support a generic handler
generic_handler = Proc.new { |params, matched_method_name| matched_method_name }
inst.add "test.handler7", &generic_handler
inst.add "test.handler8", &generic_handler
Params will be either Array, Hash, or nil.
The value yielded by the block will become the JSON-RPC result field.
Listeners are different to handlers in the way that they do not yield a response.
Because a listener does not yield a response, it is possible for many listener blocks to be called from a single request or notification.
# listen for requests and notifications but do not handle
inst.listen /test\.handler[0-9]+/ do |params, matched_method_name|
puts matched_method_name
end# nil params
result = inst.request("name.of.handler", timeout: 3)# array params
result = inst.request("name.of.handler", [], timeout: 3)# object params
result = inst.request("name.of.handler", {}, timeout: 3)- timeout is optional, it will default to 3s
- will raise
Behest::ResponseTimeoutif response is not recieved before timeout - will raise
Behest::ResponseErrorif an error is receivedBehest::ResponseError#codeBehest::ResponseError#messageBehest::ResponseError#data
# nil params
inst.notify("name.of.handler")# array params
inst.notify("name.of.handler", [])# object params
inst.notify("name.of.handler", {})