JSONRPC2 v2.0.0 JSONRPC2 View Source

JSONRPC2 is an Elixir library for JSON-RPC 2.0.

It includes request and response utility modules, a transport-agnostic server handler, a line-based TCP server and client, which are based on Ranch and shackle, respectively, and a JSON-in-the-body HTTP(S) server and client, based on Plug and hackney, respectively.

TCP Example

# Define a handler
defmodule Handler do
  use JSONRPC2.Server.Handler

  def handle_request("hello", [name]) do
    "Hello, #{name}!"
  end

  def handle_request("hello2", %{"name" => name}) do
    "Hello again, #{name}!"
  end

  def handle_request("subtract", [minuend, subtrahend]) do
    minuend - subtrahend
  end

  def handle_request("notify", [name]) do
    IO.puts "You have been notified, #{name}!"
  end
end

# Start the server (this will usually go in your OTP application's start/2)
JSONRPC2.Servers.TCP.start_listener(Handler, 8000)

# Define the client
defmodule Client do
  alias JSONRPC2.Clients.TCP

  def start(host, port) do
    TCP.start(host, port, __MODULE__)
  end

  def hello(name) do
    TCP.call(__MODULE__, "hello", [name])
  end

  def hello2(args) do
    TCP.call(__MODULE__, "hello2", Map.new(args))
  end

  def subtract(minuend, subtrahend) do
    TCP.cast(__MODULE__, "subtract", [minuend, subtrahend])
  end

  def notify(name) do
    TCP.notify(__MODULE__, "notify", [name])
  end
end

# Start the client pool (this will also usually go in your OTP application's start/2)
Client.start("localhost", 8000)

# Make a call with the client to the server
IO.inspect Client.hello("Elixir")
#=> {:ok, "Hello, Elixir!"}

# Make a call with the client to the server, using named args
IO.inspect Client.hello2(name: "Elixir")
#=> {:ok, "Hello again, Elixir!"}

# Make a call with the client to the server asynchronously
{:ok, request_id} = Client.subtract(2, 1)
IO.puts "non-blocking!"
#=> non-blocking!
IO.inspect JSONRPC2.Clients.TCP.receive_response(request_id)
#=> {:ok, 1}

# Notifications
Client.notify("Elixir")
#=> You have been notified, Elixir!

HTTP Example

# Define a handler
defmodule Handler do
  use JSONRPC2.Server.Handler

  def handle_request("hello", [name]) do
    "Hello, #{name}!"
  end

  def handle_request("hello2", %{"name" => name}) do
    "Hello again, #{name}!"
  end

  def handle_request("notify", [name]) do
    IO.puts "You have been notified, #{name}!"
  end
end

# Start the server (this will usually go in your OTP application's start/2)
JSONRPC2.Servers.HTTP.http(Handler)

# Define the client
defmodule Client do
  alias JSONRPC2.Clients.HTTP

  @url "http://localhost:4000/"

  def hello(name) do
    HTTP.call(@url, "hello", [name])
  end

  def hello2(args) do
    HTTP.call(@url, "hello2", Map.new(args))
  end

  def notify(name) do
    HTTP.notify(@url, "notify", [name])
  end
end

# Make a call with the client to the server
IO.inspect Client.hello("Elixir")
#=> {:ok, "Hello, Elixir!"}

# Make a call with the client to the server, using named args
IO.inspect Client.hello2(name: "Elixir")
#=> {:ok, "Hello again, Elixir!"}

# Notifications
Client.notify("Elixir")
#=> You have been notified, Elixir!

Serializers

Any module which conforms to the same API as Jason's Jason.encode/1 and Jason.decode/1 can be provided as a serializer to the functions which accept them.

Link to this section Summary

Types

A JSON-RPC 2.0 request ID.

A decoded JSON object.

A JSON-RPC 2.0 method.

A JSON-RPC 2.0 params value.

Link to this section Types

Specs

id() :: String.t() | number()

A JSON-RPC 2.0 request ID.

Specs

json() ::
  nil
  | true
  | false
  | float()
  | integer()
  | String.t()
  | [json()]
  | %{optional(String.t()) => json()}

A decoded JSON object.

Specs

method() :: String.t()

A JSON-RPC 2.0 method.

Specs

params() :: [term()] | %{optional(String.t() | atom()) => term()}

A JSON-RPC 2.0 params value.