README.md

# JsonRPC
[![Hex.pm](https://img.shields.io/hexpm/v/json_rpc.svg?style=flat-square)](https://hex.pm/packages/json_rpc)
![Hex.pm](https://img.shields.io/hexpm/dt/json_rpc?style=flat-square)
![GitHub Workflow Status](https://img.shields.io/github/workflow/status/hrzndhrn/json_rpc/CI?style=flat-square)
![Coveralls](https://img.shields.io/coveralls/github/hrzndhrn/json_rpc?style=flat-square)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)

An implementation of the [JSON RPC](https://www.jsonrpc.org/) protocol version 2.

This library provides functions to generate and handle JSON RPC requests,
responses and error responses. For the transport of the generate RPC data the
`behaviour` `JsonRPC.Transport` must be implemented.

## Installation

The package can be installed by adding `json_rpc` to your list of dependencies
in `mix.exs`:

```elixir
def deps do
  [
    {:json_rpc, "~> 0.1"}
    # {:jason, "~> 1.2"}
    # {:poison, "~> 5.0"}
  ]
end
```

`JsonRPC` uses `jason` per default. To customize the JSON library, including the
following in your config:
```elixir
config :json_rpc, parser: :poison
```


## Examples

This repo contains some examples of how to us `JsonRPC`.

- [SimRpc](examples/sim_rpc) shows the usage with a "simulated" server. Similar
  to the example in section Usage.
- [phx_server](examples/phx_server) shows a server implementation with a HTTP
  endpoint and a WebSocket.
- [http_client](examples/http_client) shows a HTTP client that communicates with
  the example server implemented in [phx_server](examples/phx_server)
- [ws_client](examples/ws_client) shows a WebSocket client that communicates with
  the example server implemented in [phx_server](examples/phx_server)

## Usage

A quick simple example, for more information see the
[documentation](https://hexdocs.pm/xema/readme.html) and the examples.

A client:
```elixir
defmodule Client do
  use JsonRPC, transport: Transport

  rpc add(a, b)
end
```
An implementation of the behaviour `JsonRPC.Transport`:
```elixir
defmodule Transport do
  @behaviour JsonRPC.Transport

  @impl
  def send_rpc(json, _opts) do
    Process.spawn(Transport, :server, [json], [])
    :ok
  end

  def server(json) do
    json
    |> JsonRPC.handle_request(Math)
    |> JsonRPC.handle_response()
  end
end
```
The module containing the function to be called:
```elixir
defmodule Math do
  def add(a, b), do: a + b
end
```
Using the client:
```elixir
iex> Client.add(1, 2)
{:ok, 3}
```