Skip to content

cjhdev/behest

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

behest

A transport layer agnostic implementation of JSON-RPC 2.0.

Batch is not supported.

examples

Create an Instance

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)
end

All of the options are optional:

  • logger: will default to a null logger
  • name: will default to SecureRandom.hex(4)
  • counter: will default to rand(0..2**32-1)

Route Transport Layer to Instance

It is necessary to feed messages into the instance somehow:

inst.input(input_from_transport_layer)

Disable Some Error Responses

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

Adding Method Handlers to an Instance

# 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.

Adding listeners

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

Make a Request

# 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::ResponseTimeout if response is not recieved before timeout
  • will raise Behest::ResponseError if an error is received
    • Behest::ResponseError#code
    • Behest::ResponseError#message
    • Behest::ResponseError#data

Make a Notification

# nil params
inst.notify("name.of.handler")
# array params
inst.notify("name.of.handler", [])
# object params
inst.notify("name.of.handler", {})

About

Transport layer agnostic JSON-RPC 2.0

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages